Java-8:在文件的 1 行中多次匹配 1 个模式(通过过滤器)

标签 java java-8

拥有这个数据文件:

    Test 1
    Test 2 Test 3 Test 11

I would like to have a program to match each 'Test (.)', so I will get the output:

    Match: 1
    Match: 2
    Match: 3
    Match: 11

The program below gives this output:

    Match: 1

The program is:

void addMysteries( Path path, String output) {
    Pattern p = Pattern.compile(".?Test (.)");
    try (Stream<String> lines = Files.lines( path)) {
        lines.map( p::matcher)
                .filter(Matcher::matches)
                .forEach( matcher -> System.out.println("Match: " + matcher.group(1)));
    } catch( Exception e) {
        e.printStackTrace();
    }
}

Java 7 中,下面的软件运行良好。为什么这行得通而上面的行不通?

pattern = Pattern.compile(".?Test (.)");
input = "Test 1\n\rOtherStuff\nTest 2 Test 3";
matcher = pattern.matcher(input);
while (matcher.find()) {
    System.out.println(  "Match: " + matcher.group( 1));
}   

最佳答案

你必须为每一行使用 Matcher,你的代码应该是这样的:

try (Stream<String> lines = Files.lines(path)) {
    lines.forEach(line ->
            {
                Matcher matcher = pattern.matcher(line);
                while (matcher.find()){
                    System.out.println("Match: " + matcher.group(1));
                }
            }
    );
} catch (Exception e) {
    e.printStackTrace();
}

Java 9+ 特性

在 Java 9+ 中你可以使用 Matcher#results()在第二个例子中,它可以是:

Pattern pattern = Pattern.compile(".?Test (.)");
try (Stream<String> lines = Files.lines(path)) {
    lines.forEach(input -> pattern.matcher(input)
            .results()
            .forEach(matcher -> System.out.println("Match: " + matcher.group(1)))
    );
} catch (Exception e) {
    e.printStackTrace();
}

或作为 @Holger提到你可以使用flatMapMatcher#results()像这样:

try (Stream<String> lines = Files.lines(path)) {
    lines.flatMap(input ->
            pattern.matcher(input).results()
    ).forEach(matchResult -> System.out.println("Match: " + matchResult.group(1)));
} catch (IOException e) {
    e.printStackTrace();
}

或者您甚至可以使用 Scanner 读取整个文件,您可以在其中使用 Scanner::findAll像这样返回一个流:

try (Scanner scanner = new Scanner(path)) {
    scanner.findAll(pattern).forEach(matchResult ->
            System.out.println("Match: " + matchResult.group(1))
    );
} catch (IOException e) {
    e.printStackTrace();
}

输出

Match: 1
Match: 2
Match: 3

你可以看一下@Holger 的 results()findAll() 这两个后向端口:

关于Java-8:在文件的 1 行中多次匹配 1 个模式(通过过滤器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50787034/

相关文章:

Java EE - DAO DVO

java - JAX-WS、weblogic 中的容器管理事务

java - 执行 Observables 映射

java - 在 Java 8 中将不同的方法作为参数传递

java - 打开默认 Java 信任库的最便携方法是什么?

linux - Java 8 Javadoc 与 XJC 警告和错误

java - 如何用信号量替换synchronized、wait、notify? (生产者消费者)

java - Websphere Portal Server 虚拟门户 IBM Portal API

java - 如何使用另一个类文件中定义的常量作为自定义注释中的默认值

java - Android:无法加载系统库