Java Regex前瞻需要花费太多时间

时间:2012-10-09 00:03:50

标签: java android regex

我正在尝试为我的问题创建一个正确的正则表达式,并且显然遇到了奇怪的问题。

让我描述一下我要做的事情。

我的目标是从字符串的两端删除逗号。 E,g,字符串, ,, ,,, , , Hello, my lovely, world, ,, ,应该只是Hello, my lovely, world

我准备了以下正则表达式来完成此任务: (\w+,*? *?)+(?=(,?\W+$))

它就像正则表达式验证器中的魅力一样,但是当我尝试在Android设备上运行它时,matcher.find()函数会挂起约1分钟以找到正确的匹配... 我假设,问题在于我正在使用的正面预测,但我找不到任何更好的解决方案,而不仅仅是从开头和结尾分别修剪逗号:

output = input.replaceAll("^(,?\\W?)+", ""); //replace commas at the beginning
output = output.replaceAll("(,?\\W?)+$", ""); //replace commas at the end

在Java正则表达式中,我是否缺少积极前瞻的东西?如何在开头和结尾之间检索逗号之间的字符串部分?

1 个答案:

答案 0 :(得分:8)

如果使用匹配的组,则不必使用前瞻。试试正则表达式^[\s,]*(.+?)[\s,]*$

编辑:要将其分开,^匹配行的开头,如果使用matches(),这在技术上是多余的,但在其他地方可能会有用。 [\s,]*匹配零个或多个空白字符或逗号,但是贪婪地 - 它将接受尽可能多的字符。 (.+?)匹配任何字符串,但尾随问号指示它匹配尽可能少的字符(非贪婪),并且还将内容捕获到“组1”,因为它形成第一组括号。非贪婪匹配允许最终组包含相同的零或多个逗号或空格([\s,]*)。与^一样,最终的$与该行的结尾匹配 - 对find()有用,但对matches()有用。

如果您只需要匹配空格,请将[\s,]替换为[ ,]

这应该有效:

Pattern pattern = Pattern.compile("^[\\s,]*(.+?)[\\s,]*$");
Matcher matcher = pattern.matcher(", ,, ,,, , , Hello, my lovely, world, ,, ,");
if (!matcher.matches())
    return null;
return matcher.group(1); // "Hello, my lovely, world"