尝试在Java中使用正则表达式时出现堆栈溢出

时间:2018-08-06 20:26:51

标签: java html regex recursion stack-overflow

我已经阅读了一些有关如何优化正则表达式的文章,但没有一个答案(较少的组,使用{X,Y}而不是*)似乎阻止了我的正则表达式出现堆栈溢出错误。

我正在尝试通过文件进行动态搜索。可以说我在一个很大的文件(2-4 mb)中搜索“我敢打赌你找不到我”。我的正则表达式生成器将生成正则表达式:

i(?:.|\s)*?bet(?:.|\s)*?you(?:.|\s)*?cannot(?:.|\s)*?find(?:.|\s)*?me

此正则表达式的想法是,无论单词之间有什么字符或空白,它都能找到准确的短语。但是,当我尝试使用时:

Pattern p = Pattern.compile(generatedRegex, Pattern.MULTILINE);
Matcher m = p.matcher(fileContentsAsString);
while (m.find()) {
System.out.println(m.group())
}

我收到堆栈溢出错误。我知道正则表达式使用递归,但似乎这不是正则表达式的缺点。有什么办法可以优化此正则表达式?谢谢!

答案:

Pattern p = Pattern.compile("i(?:.*)bet(?:.*)you(?:.*)cannot(?:.*)find(?:.*?)me", Pattern.DOTALL);

是我最终使用的模式/正则表达式。看起来很快,不再有堆栈溢出异常

1 个答案:

答案 0 :(得分:0)

由于您不愿意使用限定词data.frame(favs) as_data_frame(favs) list2df(favs) list_df2df(favs) matrix(unlist(favs), nr0w=length(favs), byrow=TRUE) do.call(rbind, favs) do.call(cbind, favs) ,我认为您正在回溯很多。防止回溯的一种方法是使用原子分组(*?)和/或所有格限定符(?>X)

根据评论,您还希望仅捕获最接近“下注”的“ i”,以减少整体比赛的时间。由于您想获得与其余单词最接近的“ i”,因此在我为第二个单词添加否定前瞻的地方,您也要为它的第一个单词添加否定前瞻。换句话说,(*+)将成为(?!bet)(?!i)(?!bet)。我已编辑以下代码以包含此要求。

(?!i|bet)

输出:

  

i ....打赌....您

     

ibetyou

说明 (source)

  

“不情愿的量词的工作方式是,每次尝试匹配时,它首先尝试让正则表达式的下一部分匹配。因此,它有效地在每次迭代的开始进行了前瞻,这可以会变得非常昂贵,尤其是当量化部分每次迭代仅匹配一个字符时,例如。*?“