正则表达式在使用Stream filter()时无法正常工作

5
我将尝试从使用Java 8中的新Stream时获取的行中提取特定文本。
这是我正在阅读的内容:
46 [core1]
56 [core1]
45 [core1]
45 [core2]
67 [core2]
54 [core2]

这是我目前使用的代码:

Path path = Paths.get("./src/main/resources/", "data.txt");
            try(Stream<String> lines = Files.lines(path)){
                List<Integer> temps = new ArrayList<>();
                lines
                        .filter(line -> line.contains("[core1]"))
                        .filter(line -> line.contains("(\\d+).*"))
                        .flatMapToInt(temperature -> IntStream.of(Integer.parseInt(temperature)))
                        .forEach(System.out::println);
                System.out.print(temps.size());
            }

我已经在https://www.regex101.com/上检查了正则表达式,它似乎工作正常。 此外,如果我只搜索[core1]字符串,它也能找到。
问题是当这些内容一起使用时,我得到了0个匹配项。 目前我的逻辑是读取一行,查看它属于哪个核心,然后获取它之前的数字。之后我想将它添加到一个列表中。
我在这里做错了什么?

阅读contains()的javadoc:http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#contains%28java.lang.CharSequence%29。它是否接受正则表达式? - JB Nizet
对此没有任何说明。理论上应该支持,但需要一些技巧来实现。有没有什么办法可以通过某种hackish的方式让它工作? - Kaspar
1
我猜你要使用String#matches而不是contains... 但在调用parseInt之前,你需要从行中提取整数。通过创建一个只有一个元素的IntStream来调用flatMapToInt并不是很有用。只需使用mapToInt即可... - Alexis C.
1
如果一个 JavaDoc 中写着:“当且仅当该字符串包含指定的字符值序列时返回 true”,那么不,它不支持正则表达式是很合理的。方法不会做你想让它们做的事情,而是会按照文档说明去执行。@Kaspar - JB Nizet
感谢您的输入。 - Kaspar
1
虽然与您的问题无关,但是对于单个项目,没有必要使用flatMapToInt。只需使用mapToInt即可。.mapToInt(Integer::parseInt) http://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#mapToInt-java.util.function.ToIntFunction- - Brett Okken
1个回答

11

contains仅适用于字符串(不支持正则表达式)...您可以使用line.matches("(\\d+).*")来实现相同的功能。


5
如果你的文件非常大,你可以缓存编译后的正则表达式Pattern以提高速度。Pattern是线程安全(不可变)的,因此在多线程环境下使用也是可以的。 - Giovanni Botta
4
@Giovanni Botta: 如果你有一份编译好的模式,你可以使用asPredicate来创建一个过滤器,这样你仍然可以在一行中完成:.filter(Pattern.compile("[core1]").asPredicate()) .filter(Pattern.compile("(\\d+).*").asPredicate()) - Holger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接