在任何标准库中,是否有字符类(字母、数字、字母数字)的定义?我正在检查字符串是否只包含字母数字字符或冒号:
StringUtils.containsOnly(input, ALPHA_NUMERIC + ":");
我可以自己定义ALPHA_NUMERIC,但普通字符类似乎会在标准库中定义,尽管我一直找不到定义。
edit:我确实考虑过regex,但对于我的特定用例,执行时间很重要,简单的扫描更有效。
编辑:以下是使用Regex、CharMatcher和简单扫描(每个测试使用相同的有效/无效输入字符串集)的测试结果:
有效输入字符串:
CharMatcher,运行次数:1000000,有效字符串:true,时间(ms):1200
Regex,运行次数:1000000,有效字符串:true,时间(ms):909
扫描,运行次数:1000000,有效字符串:true,时间(ms):96
无效的输入字符串:
CharMatcher,运行次数:1000000,有效字符串:false,时间(毫秒):277
Regex,运行次数:1000000,有效字符串:false,时间(ms):253
扫描,运行次数:1000000,有效字符串:false,时间(ms):36
以下是执行扫描的代码:
public boolean matches(String input) {
for(int i=0; i<input.length(); i++) {
char c = input.charAt(i);
if( !Character.isLetterOrDigit(c) && c != ':') {
return false;
}
}
return true;
}
编辑:我重新编译为一个独立的程序(我正在运行eclipse):
CharMatcherEster,运行次数:1000000,有效字符串:true,时间(毫秒):418
RegexTester,运行次数:1000000,有效字符串:true,时间(毫秒):812
ScanTester,运行次数:1000000,有效字符串:true,时间(ms):88
CharMatcherEster,运行次数:1000000,有效字符串:false,时间(毫秒):142
RegexTester,运行次数:1000000,有效字符串:false,时间(毫秒):223
ScanTester,运行次数:1000000,有效字符串:false,时间(ms):32
来源:https://bitbucket.org/jdeveloperw/testing(这是我第一次将测试结果发布到SO,所以非常感谢您的评论。)
您的最佳选择可能是regex模式。
它应该匹配:
[p{Alnum}:]*
p{Alnum}
-ASCII字母数字[]
-字符类(里面的任何字符都将与一个字符匹配):
-文字:*
-0或更多
如果它都是字母数字(或:)。
您可以使用匹配项或预编译正则表达式。
当你谈论regex
时,它确实存在,在这种情况下,字符类w
就代表了这一点。这就是String类具有matches方法的原因。
edit:StringUtils类可能早于Java 1.4中添加matches方法的时候。Apache Commons类提供的许多功能都已折叠到标准库中。当您必须使用旧版本的Java或使用标准库中没有的东西时,它们仍然很有用,但这似乎不是其中之一。
试试这个,使用正则表达式:
boolean containsOnlyAlphanumeric = input.matches("[\p{Alnum}:]+");
编辑:
为了获得最佳性能,您可以预编译模式,将其存储在静态定义的模式常量中,并在必要时重用它:
// part of the class declaration
private static final Pattern ALPHANUMERIC_PLUS_COLON = Pattern.compile("[\p{Alnum}:]+");
// whenever you need to check if the input matches the pattern
boolean containsOnlyAlphanumeric = ALPHANUMERIC_PLUS_COLON.matcher(input).matches();
我同意Matthew Flaschen的观点,你不应该立即丢弃正则表达式,一个构建良好的预编译正则表达式的速度可能与扫描输入字符串中所有可能的有效字符的速度一样快。基准先行!
Guava的CharMatcher
几乎正是您所要求的。这是维基的文章。(披露:我为Guava捐款。)
CharMatcher matcher = CharMatcher.JAVA_LETTER_OR_DIGIT.or(
CharMatcher.is(':'));
return matcher.matchesAllOf(string);
Regex匹配就可以完成这项工作。例如MyString.matches("[a-zA-Z0-9:]*");