【发布时间】:2011-05-16 11:57:29
【问题描述】:
出于某种原因,这段 Java 代码给了我重叠匹配:
Pattern pat = Pattern.compile("(" + leftContext + ")" + ".*" + "(" + rightContext + ")", Pattern.DOTALL);
任何方式/选项,以避免检测重叠?例如 leftContext rightContext rightContext 应该是 1 匹配而不是 2
这是完整的代码:
public static String replaceWithContext(String input, String leftContext, String rightContext, String newString){
Pattern pat = Pattern.compile("(" + leftContext + ")" + ".*" + "(" + rightContext + ")", Pattern.DOTALL);
Matcher matcher = pat.matcher(input);
StringBuffer buffer = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(buffer, "");
buffer.append(matcher.group(1) + newString + matcher.group(2));
}
matcher.appendTail(buffer);
return buffer.toString();
}
所以这是使用否定前瞻的最终答案,我没有意识到 * 是贪婪的:
Pattern pat = Pattern.compile("(" +
leftContext + ")" + "(?:(?!" +
rightContext + ").)*" + "(" +
rightContext + ")", Pattern.DOTALL);
【问题讨论】:
-
你能告诉我们leftContext和rightContext是什么吗?并给我们一个失败匹配的例子。
-
让正则表达式匹配器捕获重叠的东西通常是一件有点棘手的事情,而不是默认情况下发生的事情。没有看到模式的内容,很难说发生了什么。它基本上需要环顾四周才能让匹配器不止一次地遍历字符串的同一部分。你这样做吗?
-
rightContext 和 leftContext 是纯字符串,例如 leftContext="ab" rightContext="cd"
-
*量词默认是贪婪的,你描述的正则表达式不会产生多个匹配。你为什么不发布一个完整的例子? -
啊,这就是发生的事情,我有没有机会将 * 的默认行为更改为非贪婪?