Java 用于提取模式匹配组的Regex one liner

Java 用于提取模式匹配组的Regex one liner,java,regex,java-stream,Java,Regex,Java Stream,使用Java11,我想知道如何使用流API将所有组匹配提取到一个一行程序中的字符串列表 给定此regexp和字符串: String regexp = "(\\d\\d\\d)-(\\d)-(\\d\\d)"; String str = "123-8-90"; 我知道如何在多行中获得结果: Pattern pattern = Pattern.compile(regexp); Matcher matcher = pattern.matcher(str);

使用Java11,我想知道如何使用流API将所有组匹配提取到一个一行程序中的字符串列表

给定此regexp和字符串:

String regexp = "(\\d\\d\\d)-(\\d)-(\\d\\d)";
String str = "123-8-90";
我知道如何在多行中获得结果:

Pattern pattern = Pattern.compile(regexp);
Matcher matcher = pattern.matcher(str);

List<String> matches = new ArrayList<>();
if (matcher.find()) {
  matches.add(matcher.group(1));
  matches.add(matcher.group(2));
  matches.add(matcher.group(3));
}

System.out.println(matches);
Pattern=Pattern.compile(regexp);
Matcher-Matcher=pattern.Matcher(str);
列表匹配项=新的ArrayList();
if(matcher.find()){
matches.add(matcher.group(1));
matcher.add(matcher.group(2));
matcher.add(matcher.group(3));
}
System.out.println(匹配项);
这将打印3个不同数字字符串的预期列表:[123、8、90]

我试图在一条航线上实现同样的目标:

List<String> matches = Pattern.compile(regexp)
    .matcher(str)
    .results()
    .map(MatchResult::group)
    .collect(Collectors.toList());

System.out.println(matches);
List matches=Pattern.compile(regexp)
.matcher(str)
.结果()
.map(匹配结果::组)
.collect(Collectors.toList());
System.out.println(匹配项);
这将打印意外的:[123-8-90]


如何在流中使用MatchResult::group(int)方法?

您非常接近。您需要平面映射
匹配结果#组

List<String> matches = Pattern.compile(regexp)
    .matcher(str)
    .results()
    .flatMap(mr -> IntStream.rangeClosed(1, mr.groupCount())
        .mapToObj(mr::group))
    .collect(Collectors.toList());

System.out.println(matches);
List matches=Pattern.compile(regexp)
.matcher(str)
.结果()
.flatMap(mr->IntStream.rangeClosed(1,mr.groupCount())
mapToObj先生(先生:集团))
.collect(Collectors.toList());
System.out.println(匹配项);

您不必要的复杂正则表达式使您的解决方案更容易出错和复杂。有两种更简单的方法可以做到这一点:

  • 使用regex,
    \d+
    并将
    流映射到
    MatchResult::group

  • 除了使用正则表达式的解决方案外,还可以遍历字符串的字符,并将数字收集到
    列表中。与正则表达式解决方案一样,也有很多方法可以做到这一点。

    .map(MatchResult::group)
    替换为
    .flatMap(mr->IntStream.rangeClosed(1,mr.groupCount()).mapToObj(mr::group))
    您应该将其添加为答案。或者将模式更改为
    “\\d+”
    。然后,
    Pattern.compile(“\\d+”).matcher(str).results().map(MatchResult::group).collect(Collectors.toList())
    将起作用。或者只使用
    List matches=Arrays.asList(str.split(“\\D+”)
    
    import java.util.List;
    import java.util.regex.MatchResult;
    import java.util.regex.Pattern;
    import java.util.stream.Collectors;
    
    public class Main {
        public static void main(String[] args) {
            List<String> matches = 
                    Pattern.compile("\\d+")
                            .matcher("123-8-90")
                            .results()
                            .map(MatchResult::group)
                            .collect(Collectors.toList());
    
                System.out.println(matches);// [123, 8, 90]
        }
    }
    
    import java.util.Arrays;
    import java.util.List;
    
    public class Main {
        public static void main(String[] args) {
            List<String> matches = Arrays.asList("123-8-90".split("-"));
            System.out.println(matches);// [123, 8, 90]
        }
    }