在Java中寻找最长的正则表达式匹配?

pat*_*rit 15 java regex

我有这个:

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);
}
Run Code Online (Sandbox Code Playgroud)

上面只打印,hello而我想要打印hello world.

解决这个问题的一种方法是重新排序组,String regex = "(?<m2>(hello world))|(?<m1>(hello|universe))"但我无法控制我的情况下的正则表达式...

那么找到最长匹配的最佳方法是什么?一个显而易见的方法是检查s这里提到的所有可能的子串(有效地找到正则表达式的所有重叠匹配)的长度并选择第一个但是就是这样O(n^2).我们可以做得更好吗?

Sag*_*r V 1

$只需在 Or 分隔符之前添加(End of string) 即可|
然后它检查字符串是否结束。如果结束,它将返回字符串。否则跳过正则表达式的该部分。

下面的代码给出了你想要的

import java.util.regex.*;
public class RegTest{
  public static void main(String[] arg){
        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 = matcher.toMatchResult();
            String substring = s.substring(matchResult.start(), matchResult.end());
            System.out.println(substring);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

同样,下面的代码将跳过hellohello world并匹配hello world there查看there
的用法$

import java.util.regex.*;
public class RegTest{
  public static void main(String[] arg){
        String regex = "(?<m1>(hello|universe))$|(?<m2>(hello world))$|(?<m3>(hello world there))";
        String s = "hello world there";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(s);
        while(matcher.find()) {
            MatchResult matchResult = matcher.toMatchResult();
            String substring = s.substring(matchResult.start(), matchResult.end());
            System.out.println(substring);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是不正确的,例如“你好,世界!” 你不会匹配任何东西,但表达式应该匹配“hello”或“hello Universe!” 应该匹配“universe”,但你不会再匹配任何东西。 (4认同)
  • 或者“hello world hello”你会找到“hello”,但你应该找到“hello world”。你所做的基本上是一个 `endsWith()` ,它不能确保你找到最长的匹配。 (4认同)