使用 java.util.regex 提取子字符串,我发现自己实现了相同的代码模式,用于解决对以下调用的问题:
Pattern p = Pattern.compile(pattern); // can be static final
Matcher m = p.matcher(input);
if (m.find()) { // or m.matches()
foo(m.group(x));
} else {
...
}
是否有一个功能扩展或流行的库(番石榴/apache commons(可以避免丑陋的不必要和容易出错的局部变量,例如:
Pattern p = Pattern.compile(pattern); // can be static final
p.matchedGroup(input, x) // return Optional<String>
.map(group -> foo(group))
.orElse(...);
以及一系列匹配结果,例如:
Pattern p = Pattern.compile(pattern);
p.findMatches(input)
.map((MatchResult mr) -> {
mr.groupsIfPresent(x).map(g -> foo(g)).orElse(...)
})
.findFirst();
似乎 Java8 中唯一的功能添加是.splitAsStream()
但这仅在尝试围绕匹配进行拆分时才有帮助。
仅在java-9中可用
您可能正在寻找产生Stream<MatchResult>
的Matcher::results
您可以通过以下方式使用它,例如
p.matcher(input)
.results()
.map(MatchResult::group)
.findAny()
.orElse(null);
Holger 添加的一个附加功能是,在读取File
并寻找直接使用Scanner::findAll
的模式时,以避免使用File::lines
将整个文件加载到内存中
有一个优雅的解决方案,适用于Stream<String>
和Optional<String>
:
Pattern pattern = Pattern.compile("...");
List<String> input = new ArrayList<>();
List<String> matches = input.stream()
.map(pattern::matcher)
.filter(Matcher::find)
.map(m -> m.group(x))
.collect(Collectors.toList());
虽然我想指出,在filter
调用中进行修改/更改操作是不寻常的。在filter
调用中进行变更操作时请小心,并尽可能避免它们。对于这种情况,这很好(从我的主观角度来看(,因为您修改了刚刚在流中创建的对象,该对象未在流操作之外使用。
当您只有一个输入时,请使用Optional.ofNullable/of
,其他所有内容看起来都一样。