如何正确使用java Pattern对象来匹配字符串模式

时间:2014-07-15 05:11:44

标签: java regex string out-of-memory

我编写了一个执行多个字符串操作的代码,包括检查给定字符串是否与某个正则表达式匹配。它运行得很好,有70,000个输入,但当我迭代运行它进行五次交叉验证时,它开始给我出现内存错误。我可能需要分配更多内存,但我觉得我可能编写了一个效率低下的代码,所以想要仔细检查一下我是否犯了任何明显的错误。

     static Pattern numberPattern = Pattern.compile("^[a-zA-Z]*([0-9]+).*");
     public static boolean someMethod(String line) {
         String[] tokens = line.split(" ");
         for(int i=0; i<tokens.length; i++) {
             tokens[i] = tokens[i].replace(",", "");
             tokens[i] = tokens[i].replace(";", "");
             if(numberPattern.matcher(tokens[i]).find()) return true; 
          }
    return false;
}

我也有很多行如下:

        token.matches("[a-z]+[A-Z][a-z]+"); 

哪种方式更节省内存?它们看起来足够有效吗?任何建议表示赞赏!

编辑:

抱歉,我的错误代码,我打算在发布此问题之前修改,但我忘记了最后一刻。但问题是我有很多类似的外观操作,除了示例代码没有意义的事实,我想知道regexp比较部分是否有效。

感谢您的所有评论,我将按照建议查看并修改代码!

4 个答案:

答案 0 :(得分:2)

嗯,首先,再试一下你的代码...它总会返回一个&#34; true&#34;价值!你没有阅读比赛&#39;变量,只是放价值......

第二,String是不可变的,因此,每次你分裂时,你都会创建另一个实例......为什么不尝试这样做呢?创建一个模式来制作你想要的匹配忽略逗号和分号?我不确定,但我认为这会减少记忆......

答案 1 :(得分:1)

是的,这段代码效率很低,因为一旦找到match = true;(没有点继续循环),你就可以立即返回。

此外,您确定需要将该行划分为tokens吗?为什么不检查一次正则表达式呢?

最后,如果所有比较检查都失败了,您应该返回false(最后一行)。

答案 2 :(得分:1)

不是改变文本并将其拆分,而是将其全部放在正则表达式中。

// the \\b means it must be the start of the String or a word
static Pattern numberPattern = Pattern.compile("\\b[a-zA-Z,;]*[0-9,;]*[0-9]");

// return true if the string contains 
// a number which might have letters in front
public static boolean someMethod(String line) {
     return numberPattern.matcher(line).find());
}

答案 3 :(得分:0)

除了@alfasin在答案中提到的内容之外,你应该避免重复代码;重写以下内容:

{
    tokens[i] = tokens[i].replace(",", "");
    tokens[i] = tokens[i].replace(";", "");
}

分为:

tokens[i] = tokens[i].replaceAll(",|;", "");

请在.split()之前计算一下,这样就不必在循环中重复操作了:

String[] tokens = line.replaceAll(",|;", "").split(" ");
                      ^^^^^^^^^^^^^^^^^^^^^^

编辑:在稍微盯着你的代码后我觉得我有一个更好的解决方案,使用正则表达式;)

public static boolean someMethod(String line) {
    return Pattern.compile("\\b[a-zA-Z]*\\d")
             .matcher(line.replaceAll(",|;", "")).find();
}

Online Regex Demo
Online Code Demo

  • \b是一个词边界。
  • 它在一个单词的边界处断言位置(行间距+间隔后)

代码演示STDOUT:

  

foo不匹配
  酒吧不匹配
  bar1匹配
  foo baz bar bar1 lolz确实匹配
  password_01不匹配