分享
为什么问答平台  ›  专栏  ›  技术社区  ›  tkruse

函数样式java.util.regex match/group extraction - Functional style java.util.regex match/group extraction

  •  3
  • tkruse  · 技术社区  · 1 周前

    使用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 {
        ...
    }
    

    是否有一个函数扩展或流行库(guava/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() 但这只会在比赛中有所帮助。

    2 回复  |  直到 1 周前
        1
  •  3
  •   Yassin Hajaj    1 周前

    以下仅可从

    你可能在找 Matcher::results 它产生一个 Stream<MatchResult>

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

    p.matcher(input)
     .results()
     .map(MatchResult::group)
     .findAny()
     .orElse(null);
    
        2
  •  4
  •   roookeee    1 周前

    有一个优雅的解决方案可以同时适用于两者 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 -打电话是不寻常的。在中执行转换操作时请小心 滤波器 尽可能避免打电话。对于这种情况,尽管(从我的主观观点来看)可以修改刚刚在流中创建的对象,但该对象不在流操作之外使用。

    使用 Optional.ofNullable/of 当您只有一个输入时,其他一切看起来都一样。