regex 调用string.matches(PATTERN)给出的结果与Pattern.compile(PATTERN).matcher(string).hasMatches()不同

1bqhqjot  于 2023-08-08  发布在  其他
关注(0)|答案(2)|浏览(98)

我正试图写一个小的java库,目前我正试图逐行读取文件,如果在一行中我找到表达式“!includes .yaml”我想获取文件名,加载它并将其替换到我正在阅读的当前文件中。例如,在订单文件中:

orderNo: A001
date: 2019-04-17
customerName: Customer, Joe
orderLines:
  - item: No. 9 Sprockets
    quantity: 12
    unitPrice: 1.23
  - item: Widget (10mm)
    quantity: 4
    unitPrice: 3.45
  - !include item.yaml

字符串
我想用文件item.yaml的内容替换最后一行,它看起来像这样

item: Sub-item
quantity: 2
unitPrice: 16


为此,我目前正在使用正则表达式来匹配整个“!includes .yaml”,看起来像这样:

private static final Pattern includePattern = Pattern.compile(".*!include (?<fileName>.*\\.(yaml|yml))");
    public static String readConfiguration(String configurationFile) {
        final var configurationFileUrl = ConfigurationLoader.class.getClassLoader().getResource(configurationFile);
        if (configurationFileUrl == null)
            throw new ConfigurationReadException(configurationFile);
        try {
            final var lines = Files.readAllLines(Path.of(configurationFileUrl.toURI()));
            for (final var line : lines) {
                final var matcher = includePattern.matcher(line);
                if (matcher.hasMatch()) {
                    final var includedFileName = matcher.group("fileName");
                    final var includedConfiguration = readConfiguration(includedFileName);
                }
            }
            return lines.stream().reduce("", (existing, current) -> existing.equals("") ? current : "%s\r\n%s".formatted(existing, current));
        } catch (IOException | OutOfMemoryError | SecurityException | IllegalArgumentException |
                 FileSystemNotFoundException | URISyntaxException e) {
            throw new ConfigurationReadException(configurationFile.toString(), e);
        }
    }


现在我的问题是matcher.hasMatch()总是返回false,匹配器在组上没有匹配,即使当我调试到代码中的那个位置并执行line.matches(includePattern.pattern)时,我实际上得到了“true”。
我知道.hasMatches/matches只在整个字符串匹配正则表达式时返回true,但这就是为什么我修改了我的模式,使它实际上应该匹配整行。使用在线正则表达式测试人员进行测试也告诉我,我的正则表达式应该可以工作。我做错了什么?

gj3fmq9x

gj3fmq9x1#

很高兴听到你解决了问题。

  • Matcher* 类动态工作。这意味着,您必须调用它来生成输出。

它在示例化时不会有所有的数据。
因此,对于 hasMatch 方法,正如您提到的,它最初需要一个匹配。

  • "...返回是否包含来自上一个匹配或查找操作的有效匹配。..."*

注意,在这种情况下,我通常使用 find 方法。

if (matcher.find()) {
    final var includedFileName = matcher.group("fileName");
    final var includedConfiguration = readConfiguration(includedFileName);
}

字符串
最后一点,你可以减少模式。
初始.*、捕获组和集合并集都是必需的。

!include (?<fileName>.*\.ya?ml)

hgc7kmma

hgc7kmma2#

好吧,在发布我的问题5分钟后,我在一个小时前搜索后在另一个线程中找到了答案。final var matcher = includePattern.matcher(line);在调用匹配器上的任何其他方法之前必须调用matcher.matches()

相关问题