29

检查字符串是否仅包含字母数字字符的最快方法是什么。

我有一些代码会占用大量 CPU,我想知道是否有比使用预编译正则表达式更快的方法。

4

3 回答 3

46

使用String.matches(),例如:

String myString = "qwerty123456";
System.out.println(myString.matches("[A-Za-z0-9]+"));

这可能不是绝对“最快”的方法。但总的来说,在性能方面试图与编写该语言的“标准库”的人竞争并没有多大意义。

于 2012-10-11T03:30:03.863 回答
29

我已经编写了使用正则表达式(根据其他答案)与不使用正则表达式进行比较的测试。在运行 Java 1.6 的四核 OSX10.8 机器上进行的测试

有趣的是,使用正则表达式比手动迭代字符串要慢 5-10 倍。此外,该isAlphanumeric2()功能比 略快isAlphanumeric()。一种支持允许扩展 Unicode 数字的情况,另一种支持仅允许标准 ASCII 数字的情况。

public class QuickTest extends TestCase {

    private final int reps = 1000000;

    public void testRegexp() {
        for(int i = 0; i < reps; i++)
            ("ab4r3rgf"+i).matches("[a-zA-Z0-9]");
    }

public void testIsAlphanumeric() {
    for(int i = 0; i < reps; i++)
        isAlphanumeric("ab4r3rgf"+i);
}

public void testIsAlphanumeric2() {
    for(int i = 0; i < reps; i++)
        isAlphanumeric2("ab4r3rgf"+i);
}

    public boolean isAlphanumeric(String str) {
        for (int i=0; i<str.length(); i++) {
            char c = str.charAt(i);
            if (!Character.isLetterOrDigit(c))
                return false;
        }

        return true;
    }

    public boolean isAlphanumeric2(String str) {
        for (int i=0; i<str.length(); i++) {
            char c = str.charAt(i);
            if (c < 0x30 || (c >= 0x3a && c <= 0x40) || (c > 0x5a && c <= 0x60) || c > 0x7a)
                return false;
        }
        return true;
    }

}
于 2012-10-11T04:03:53.017 回答
2

正则表达式可能会非常有效,因为您将指定范围:[0-9a-zA-Z]。假设正则表达式的实现代码是有效的,这将只需要对每个范围进行上限和下限比较。这基本上是编译的正则表达式应该做的:

boolean isAlphanumeric(String str) {
    for (int i=0; i<str.length(); i++) {
        char c = str.charAt(i);
        if (c < 0x30 || (c >= 0x3a && c <= 0x40) || (c > 0x5a && c <= 0x60) || c > 0x7a)
            return false;
    }

    return true;
}

我看不出你的代码怎么能比这更有效,因为每个字符都需要检查,而且比较真的再简单不过了。

于 2012-10-11T03:48:40.907 回答