简体   繁体   English

正则表达式一个衬里来提取模式匹配组

[英]Regex one liner to extract pattern matching groups

Using Java 11 I wonder how I can use the Stream API to extract all the group matches to a list of strings in a one-liner.使用 Java 11 我想知道如何使用 Stream API 将所有组匹配项提取到单行中的字符串列表中。

Given this regexp and string:给定这个正则表达式和字符串:

String regexp = "(\\d\\d\\d)-(\\d)-(\\d\\d)";
String str = "123-8-90";

I know how to obtain the result in multiple lines:我知道如何在多行中获得结果:

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);

This prints the expected list of 3 distinct numeric strings: [123, 8, 90]这将打印 3 个不同数字字符串的预期列表: [123, 8, 90]

My attempt to achieve the same in one liner:我试图在一个班轮中实现同样的目标:

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

System.out.println(matches);

This prints the unexpected: [123-8-90]这会打印出意外: [123-8-90]

How can I use the MatchResult::group(int) method in the stream?如何在 stream 中使用 MatchResult::group(int) 方法?

You were pretty close.你非常接近。 You need to flat map the MatchResult#group :你需要平 map MatchResult#group

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);

Your unnecessarily complex regex has made your solution error-prone and complicated.您不必要的复杂正则表达式使您的解决方案容易出错且复杂。 A couple of the easier ways to do it can be:一些更简单的方法可以是:

  1. Use the regex, \d+ and map the Stream to MatchResult::group .使用正则表达式\d+和 map StreamMatchResult::group
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]
    }
}

ONLINE DEMO在线演示

  1. Split on -拆分-
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]
    }
}

ONLINE DEMO在线演示

In addition to solutions using regex, the characters of the string can be traversed and the numbers can be collected into a List .除了使用正则表达式的解决方案外,还可以遍历字符串的字符并将数字收集到List中。 As with regex solutions, there can be many ways to do this as well.与正则表达式解决方案一样,也有很多方法可以做到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM