我正试图写一个小的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,但这就是为什么我修改了我的模式,使它实际上应该匹配整行。使用在线正则表达式测试人员进行测试也告诉我,我的正则表达式应该可以工作。我做错了什么?
2条答案
按热度按时间gj3fmq9x1#
很高兴听到你解决了问题。
它在示例化时不会有所有的数据。
因此,对于 hasMatch 方法,正如您提到的,它最初需要一个匹配。
注意,在这种情况下,我通常使用 find 方法。
字符串
最后一点,你可以减少模式。
初始
.*
、捕获组和集合并集都是必需的。型
hgc7kmma2#
好吧,在发布我的问题5分钟后,我在一个小时前搜索后在另一个线程中找到了答案。
final var matcher = includePattern.matcher(line);
在调用匹配器上的任何其他方法之前必须调用matcher.matches()
。