假设任何给定的字符串:如何根据预定义的字符集验证它?
我想使用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
}
答案 0 :(得分:1)
使用与ASCII 65-90对应的unicode字符范围:
String test = "ASDQWE!&";
if (test.matches("[\u0041-\u005A]*")) {
System.out.println("match!");
}
您的示例字符串实际上并不匹配ASCII 65-90,但ASDQWE
,最后没有标点符号,是。
答案 1 :(得分:1)
我很好奇并决定将其与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
会更快,但在使用正则表达式时它肯定更具可读性。
答案 2 :(得分:0)
最好使用正则表达式。因为您可以使用正则表达式验证O(n)复杂度,但逐个匹配字符将具有O(m * n)复杂度。