如何在java中获得Regex的良好性能

时间:2009-11-16 15:24:36

标签: java regex performance

以下是文字示例:

String id = "A:abc,X:def,F:xyz,A:jkl";

以下是正则表达式:

Pattern p = Pattern.compile("(.*,)?[AC]:[^:]+$");
if(p.matcher(id).matches()) {
  System.out.println("Hello world!")
}

执行上面代码时应打印Hello world!。

是否可以修改此正则表达式以获得更高的性能?

4 个答案:

答案 0 :(得分:8)

由于我看不到你的整个代码,我只能假设你在loop / method / etc中进行模式编译。可以提高性能的一件事是在类级别进行编译,而不是每次都重新编译模式。除此之外,我没有看到你可以改变的其他内容。

答案 1 :(得分:3)

Pattern p = Pattern.compile(".*[AC]:[^:]+$");
if(p.matcher(id).matches()) {
  System.out.println("Hello world!")
}

因为你似乎只感兴趣,如果字符串以 A C 结尾,后跟冒号和一些不是冒号的字符,你可以使用{ {1}}而不是.*(或者你真的想在最后一块之前捕获这些东西吗?)

如果结肠后的东西都是小写的话你甚至可以做

(.*,)?

如果要连续多次匹配(例如循环),请确保在循环外编译模式。

E,G

Pattern p = Pattern.compile(".*[AC]:[a-z]+$");

答案 2 :(得分:1)

Pattern实例化移动到最终的静态字段( erm,常量),在当前代码中,每次重新编译基本相同的Pattern(不, Pattern不会缓存任何内容!)。这应该会给你带来明显的性能提升。

答案 3 :(得分:0)

你甚至需要使用regualr表达式吗?你正在测试的东西似乎并不多。

如果你需要像其他人所说的那样使用正则表达式,只编译一次是有道理的,如果你只需要检查最后一个令牌,你可以将正则表达式简化为:[AC]:[^:]{3}$

您是否可以沿着这些方向使用某些内容(未经测试......)?

private boolean isId(String id)
    {
        char[] chars = id.toCharArray();
        boolean valid = false;
        int length = chars.length;

        if (length >= 5 && chars[length - 4] == ':')
        {
            char fifthToLast = chars[length - 5];

            if (fifthToLast == 'A' || fifthToLast == 'C')
            {
                valid = true;

                for (int i = length - 1; i >= length - 4; i--)
                {
                    if (chars[i] == ':')
                    {
                        valid = false;
                        break;
                    }
                }
            }
        }

        return valid;
    }