我已经阅读了一些有关如何优化正则表达式的文章,但没有一个答案(较少的组,使用{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);
是我最终使用的模式/正则表达式。看起来很快,不再有堆栈溢出异常
答案 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):
“不情愿的量词的工作方式是,每次尝试匹配时,它首先尝试让正则表达式的下一部分匹配。因此,它有效地在每次迭代的开始进行了前瞻,这可以会变得非常昂贵,尤其是当量化部分每次迭代仅匹配一个字符时,例如。*?“