Как проверить строку с набором символов? - PullRequest
0 голосов
/ 04 июня 2018

Предположим любую заданную строку: как я могу проверить ее по заранее определенному набору символов?Я хотел бы использовать ASCII 65-90 (A-Z), 33 (!), 36 ($), 38 (&), 63 (?).

Нужно ли применять регулярное выражение для полной строки?Или лучше читать строку char по char и сопоставлять Integer в предопределенном диапазоне?

String test = "ASDQWE!&";
for (int i = 0; i < test.length; i++) {
        int num = (int) val.charAt(i);
        //TODO validate
}

Ответы [ 3 ]

0 голосов
/ 04 июня 2018

Мне было любопытно и я решил сравнить его с JMH;вот что я нашел:

@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Fork(3)
public class MyBenchmark {

    @Param({"ASDQWE!&"})
    private String test;

    private static final Pattern PATTERN = Pattern.compile("[A-Z!$&?]*");

    public static void main(String[] args) throws Exception {
        org.openjdk.jmh.Main.main(args);
    }

    @Benchmark
    public boolean oldMethod() {
        for (int i = 0; i < test.length(); i++) {
            int c = test.charAt(i);

            if (c >= 65 && c <= 90) {
                continue;
            }

            switch (test.charAt(i)) {
                case 33:
                case 36:
                case 38:
                case 63:
                    break;
                default:
                    return false;
            }
        }
        return true;
    }

    @Benchmark
    public boolean newMethod() {
        return PATTERN.matcher(test).matches();
    }
}

И его результаты:

Benchmark                (test)  Mode  Cnt   Score   Error  Units
MyBenchmark.newMethod  ASDQWE!&  avgt   30  55.848 ± 1.275  ns/op
MyBenchmark.oldMethod  ASDQWE!&  avgt   30  14.586 ± 0.034  ns/op

Даже с компиляцией шаблона ясно, что итерация по String будет быстрее, но это определенно большечитается при использовании регулярного выражения.

0 голосов
/ 05 июня 2018

Лучше использовать регулярные выражения.Потому что вы можете проверить с помощью регулярного выражения в сложности O (n), но совпадение символа один за другим будет иметь сложность O (m * n).

0 голосов
/ 04 июня 2018

Используйте диапазон символов Unicode, соответствующий ASCII 65-90:

String test = "ASDQWE!&";
if (test.matches("[\u0041-\u005A]*")) {
    System.out.println("match!");
}

Ваша примерная строка на самом деле не соответствует ASCII 65-90, но ASDQWE, без пунктуации в конце, is.

Демо

...