2

在任何标准库中是否有字符类(字母、数字、字母数字)的定义?我正在检查字符串是否仅包含字母数字字符或冒号:

StringUtils.containsOnly(input, ALPHA_NUMERIC + ":");

我可以自己定义 ALPHA_NUMERIC,但似乎通用字符类将在标准库中定义,尽管我一直无法找到定义。

编辑:我确实考虑过正则表达式,但对于我的特定用例,执行时间很重要,简单的扫描更有效。

编辑:这里是使用 Regex、CharMatcher 和简单扫描的测试结果(对每个测试使用相同的一组有效/无效输入字符串):

有效输入字符串:

CharMatcher,运行次数:1000000,有效字符串:true,时间(毫秒):1200

正则表达式,运行次数:1000000,有效字符串:true,时间(毫秒):909

扫描,运行次数:1000000,有效字符串:true,时间(毫秒):96

无效的输入字符串:

CharMatcher,运行次数:1000000,有效字符串:false,时间(毫秒):277

正则表达式,运行次数:1000000,有效字符串:false,时间(毫秒):253

扫描,运行次数:1000000,有效字符串:false,时间(毫秒):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 运行):

CharMatcherTester,运行次数:1000000,有效字符串:true,时间(毫秒):418

RegexTester,运行次数:1000000,有效字符串:true,时间(毫秒):812

ScanTester,运行次数:1000000,有效字符串:true,时间(毫秒):88

CharMatcherTester,运行次数:1000000,有效字符串:false,时间(毫秒):142

RegexTester,运行次数:1000000,有效字符串:false,时间(毫秒):223

ScanTester,运行次数:1000000,有效字符串:false,时间(毫秒):32

来源:https ://bitbucket.org/jdeveloperw/testing (这是我第一次将测试结果发布到 SO,因此感谢您的评论。)

4

5 回答 5

5

您最好的选择可能是正则表达式Pattern

它应该匹配:

[\p{Alnum}:]*
  • \p{Alnum}- ASCII 字母数字
  • []- 字符类(里面的任何字符都会匹配一个字符)
  • :- 字面意思:
  • *- 0 个或更多

如果都是字母数字(或:)。

您可以使用匹配或预编译正则表达式。

于 2012-04-06T00:38:42.833 回答
2

试试这个,使用正则表达式:

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 的观点,您不应该立即丢弃正则表达式,一个精心构建的预编译正则表达式可以与检查输入字符串中所有可能的有效字符的扫描一样快。基准第一!

于 2012-04-06T00:42:38.207 回答
2

好吧,当您谈论regex在这种情况下,字符类\w就代表它时,它确实存在。这就是 String 类具有matches方法的原因。

编辑:当添加matches方法时,那个StringUtils类可能早于Java 1.4。Apache Commons 类提供的许多功能已被合并到标准库中。当您必须使用旧版本的 Java 或使用标准库中没有的东西时,它们仍然很有用,但这似乎不是其中一种情况。

于 2012-04-06T00:40:56.047 回答
1

番石榴 CharMatcher几乎正是您所要求的。这是维基文章。(披露:我为 Guava 做出了贡献。)

CharMatcher matcher = CharMatcher.JAVA_LETTER_OR_DIGIT.or(
  CharMatcher.is(':'));
return matcher.matchesAllOf(string);
于 2012-04-06T01:42:54.567 回答
0

正则表达式匹配可以完成这项工作。例如 MyString.matches("[a-zA-Z0-9:]*");

于 2012-04-06T00:47:06.340 回答