【问题标题】:Regex not working with Stream filter()正则表达式不适用于流过滤器()
【发布时间】:2015-04-22 18:58:24
【问题描述】:

我试图从在 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:docs.oracle.com/javase/7/docs/api/java/lang/…。它接受正则表达式吗?
  • 什么也没说。有强硬的支持是合乎逻辑的。有什么方法可以让它以某种骇人听闻的方式工作?
  • 我猜你正在寻找String#matches而不是contains...虽然你需要在调用parseInt之前从行中提取整数。通过创建一个带有一个元素的IntStream 来调用flatMapToInt 并不是很有用。只需改用mapToInt...
  • @Kaspar 如果 javadoc 说:“当且仅当此字符串包含指定的 char 值序列时才返回 true。”,那么不,支持正则表达式是不合逻辑的。方法不会像你认为的那样做。他们按照文档上说的去做。
  • 与您的问题无关,但单个项目无需 flatMapToInt。简单使用 mapToInt。 .mapToInt(Integer::parseInt)docs.oracle.com/javase/8/docs/api/java/util/stream/…

标签: java regex lambda java-8 java-stream


【解决方案1】:

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

【讨论】:

  • 如果你的文件很大,你可以缓存编译的正则表达式Pattern以提高速度。 Pattern 是线程安全的(不可变的),因此如果需要,您甚至可以在多线程上下文中使用它。
  • @Giovanni Botta:对,如果你有编译模式,你可以使用asPredicate来创建一个过滤器,所以你仍然可以在一行中完成:.filter(Pattern.compile("[core1]").asPredicate()) .filter(Pattern.compile("(\\d+).*").asPredicate())
猜你喜欢
  • 2013-05-01
  • 2020-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-22
  • 1970-01-01
相关资源
最近更新 更多