为了账号安全,请及时绑定邮箱和手机立即绑定

匹配正则表达式中的最长字符串或在常见子字符串的情况下

匹配正则表达式中的最长字符串或在常见子字符串的情况下

撒科打诨 2022-06-30 18:31:59
在正则表达式 OR 中,当有多个具有公共前缀的输入时,正则表达式将匹配第一个输入Regex OR而不是最长匹配。例如,对于正则表达式regex = (KA|KARNATAKA),input = KARNATAKA输出将是 2 个匹配项match1 =KA和match2 = KA.但是我想要的Regex OR是match1 = KARNATAKA在我给定示例中的给定输入中完成最长可能匹配。这是正则表达式客户端中的示例所以我现在正在做的是,我Regex OR按长度按降序对输入进行排序。我的问题是,我们可以在正则表达式本身中指定匹配最长的字符串吗?还是排序是唯一的方法?我已经提到了这个问题,除了排序我没有看到其他解决方案
查看完整描述

2 回答

?
侃侃无极

TA贡献2051条经验 获得超10个赞

您可以使用单词边界 ( \b) 来避免匹配前缀

对于您提到的情况:以下正则表达式将仅匹配KAKARNATAKA

(\bKA\b|\bKARNATAKA\b)

在这里试试


查看完整回答
反对 回复 2022-06-30
?
繁星点点滴滴

TA贡献1803条经验 获得超3个赞

您可以为此创建一个辅助方法:


public final class PatternHelper {

    public static Pattern compileSortedOr(String regex) {

        Matcher matcher = Pattern.compile("(.*)\\((.*\\|.*)\\)(.*)").matcher(regex);


        if (matcher.matches()) {

            List<String> conditions = Arrays.asList(matcher.group(2).split("\\|"));

            List<String> sortedConditions = conditions.stream()

                                                      .sorted((c1, c2) -> c2.length() - c1.length())

                                                      .collect(Collectors.toList());


            return Pattern.compile(matcher.group(1) +

                                       "(" +

                                       String.join("|", sortedConditions) +

                                       ")" +

                                       matcher.group(3));

        }


        return Pattern.compile(regex);

    }

}


Matcher matcher = PatternHelper.compileSortedOr("(KA|KARNATAKA)").matcher("KARNATAKA");

if (matcher.matches()) {

    System.out.println(matcher.group(1));

}

输出:


KARNATAKA

PS 这仅适用于没有嵌套括号的简单表达式。如果您期望非常复杂的表达式,则需要进行调整。


查看完整回答
反对 回复 2022-06-30
  • 2 回答
  • 0 关注
  • 175 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信