在公共子字符串的情况下匹配Regex中的最长字符串OR

问题描述 投票:1回答:2

在正则表达式OR中,当有多个具有公共前缀的输入时,正则表达式将匹配Regex OR中的第一个输入而不是最长匹配。

例如,对于正则表达式regex = (KA|KARNATAKA)input = KARNATAKA,输出将是2匹配match1 =KAmatch2 = KA

但我想要的是在Regex OR中给定输入完成最长的匹配,在我给出的例子中是match1 = KARNATAKA

Here is the example in a regex client

所以我现在正在做的是,我按照长度按降序排序Regex OR中的输入。

我的问题是,我们可以在正则表达式中指定匹配最长的字符串吗?或者排序是唯一的方法吗?

I have already refered this question and I don't see a solution other than sorting

java regex regex-greedy
2个回答
1
投票

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

对于你提到的情况:以下正则表达式只匹配KAKARNATAKA

(\bKA\b|\bKARNATAKA\b)

Try here


0
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.