【发布时间】:2017-07-18 19:23:09
【问题描述】:
我有这个:
import java.util.regex.*;
String regex = "(?<m1>(hello|universe))|(?<m2>(hello world))";
String s = "hello world";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(s);
while(matcher.find()) {
MatchResult matchResult = m.toMatchResult();
String substring = s.substring(matchResult.start(), matchResult.end());
System.out.println(substring);
}
上面只打印hello,而我希望它打印hello world。
解决此问题的一种方法是对String regex = "(?<m2>(hello world))|(?<m1>(hello|universe))" 中的组重新排序,但我无法控制我在我的情况下得到的正则表达式...
那么找到最长匹配项的最佳方法是什么?一个明显的方法是按长度检查s 的所有可能子字符串(Efficiently finding all overlapping matches for a regular expression),然后选择第一个,但那是O(n^2)。我们能做得更好吗?
【问题讨论】:
-
使用
"(?<m1>hello world)|(?<m2>hello|universe)",将最长的替代分支放在最短的之前。 -
@WiktorStribiżew:您没有阅读我的问题。我明确表示这是我无法追求的替代方案。
-
@pathikrit 如果您要动态插入交替,您有足够的控制权来重新排序(对于像这样的动态场景,我更喜欢反向字母顺序)。前几天我刚刚回答了一个类似的问题stackoverflow.com/questions/42432356/…
-
你是个有趣的家伙,pathikrit。您想通过查看症状而不是根本原因来治愈疾病。这就像服用阿司匹林来对抗可手术脑肿瘤引起的头痛。如果正则表达式超出您的控制范围并且做错了事,要么根本不使用它,而是使用您自己的正则表达式,或者与维护正则表达式生成器的人交谈,以便让他在上游为您修复它。
-
@pathikrit,如果正则表达式总是非常简单和一致,只需编辑它并使用编辑后的版本来匹配。