在文件流上应用模式

时间:2016-01-28 15:53:54

标签: java lambda java-8

public final Pattern PATTERN = Pattern.compile("<abc:c\\sabc:name=\"(\\S+)\"\\sabc:type=\"(\\S+)\">");
    try (Stream<String> stream = Files.lines(template.getPath())) {
        stream.filter(s -> PATTERN.matcher(s).find()).forEach(System.out::println);

    } catch (IOException e) {
        e.printStackTrace();
    }

模式运行正常,但我如何捕获/获取我的组?目前我只得到了弦乐。

1 个答案:

答案 0 :(得分:7)

如果您应用的模式只显示一行一次,您可以将Stream<String>映射到Stream<Matcher>,过滤与模式匹配的行,最后提取组1和2将它们存储在一个数组中。

try (Stream<String> stream = Files.lines(Paths.get(""))) {
    stream.map(PATTERN::matcher)
          .filter(Matcher::find)
          .map(m -> new String[] { m.group(1), m.group(2) })
          .forEach(a -> System.out.println(Arrays.toString(a)));
} catch (IOException e) {
    e.printStackTrace();
}

如果模式出现多次,我们需要遍历匹配器,直到find()返回false。在这种情况下,我们可以

try (Stream<String> stream = Files.lines(Paths.get(""))) {
    stream.map(PATTERN::matcher)
          .flatMap(m -> {
              List<String[]> list = new ArrayList<>();
              while (m.find()) {
                  list.add(new String[] { m.group(1), m.group(2) });
              }
              return list.stream();
          })
          .forEach(a -> System.out.println(Arrays.toString(a)));

在Java 9中,可能有一个新方法Matcher.results()来检索Stream<MatchResult>个结果。我们可以在此处使用它,而不是进行2次单独的findgroup操作。