功能样式java.util.regex匹配/组提取

tkr*_*use 6 java regex java-9

使用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 {
    ...
}
Run Code Online (Sandbox Code Playgroud)

是否有功能扩展或流行的库(番石榴/ apache通用),避免了不必要的,容易出错的局部变量,例如:

Pattern p = Pattern.compile(pattern); // can be static final
p.matchedGroup(input, x) // return Optional<String>
    .map(group -> foo(group))
    .orElse(...);
Run Code Online (Sandbox Code Playgroud)

以及一系列匹配结果,例如:

Pattern p = Pattern.compile(pattern);
p.findMatches(input)
    .map((MatchResult mr) -> {
        mr.groupsIfPresent(x).map(g -> foo(g)).orElse(...)
    })
    .findFirst();
Run Code Online (Sandbox Code Playgroud)

似乎Java8中唯一的功能性添加是,.splitAsStream()但是仅在尝试拆分匹配项时才有用。

roo*_*eee 6

有一个适用于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());
Run Code Online (Sandbox Code Playgroud)

尽管我想指出,在filter-call 中进行修改/变异操作是不寻常的。在filter呼叫中进行变异操作时请小心,并尽可能避免。对于这种情况,(从我的主观角度来看)很好,因为您修改了刚在流中创建的,未在流操作之外使用的对象。

使用Optional.ofNullable/of时,你只有一个输入,一切看起来是一样的。

  • 赞成,因为它适用于java8,但是接受java9回答作为将来的方法。 (2认同)

Yas*_*jaj 6

以下仅适用于

您可能正在寻找Matcher::results哪个会产生Stream<MatchResult>

您可以通过以下方式使用它,例如

p.matcher(input)
 .results()
 .map(MatchResult::group)
 .findAny()
 .orElse(null);
Run Code Online (Sandbox Code Playgroud)

Holger添加的一个有趣的附加内容是,在读取a File并寻找可直接使用的模式时Scanner::findAll避免使用以下方法将整个文件加载到内存中File::lines