Соответствует самой длинной строке в регулярном выражении ИЛИ в случае общей подстроки - PullRequest
0 голосов
/ 21 февраля 2019

В регулярном выражении ИЛИ, когда есть несколько входов с общим префиксом, регулярное выражение будет соответствовать первому входу в Regex OR вместо самого длинного соответствия.

Например, для регулярного выражения regex = (KA|KARNATAKA) и input = KARNATAKA на выходе будет 2 совпадения match1 =KA и match2 = KA.

Но я хочу получить максимально длинное совпадение с заданным значением в Regex OR, которое в моем данном примере равно match1 = KARNATAKA.

Вот пример в клиенте регулярных выражений

Итак, что я сейчас делаю, я сортирую входные данные в Regex OR по длине в порядке убывания.

Мой вопрос: можем ли мы указать само регулярное выражениесоответствовать самой длинной строке?Или сортировка - единственный способ сделать это?

Я уже упоминал этот вопрос и не вижу другого решения, кроме сортировки

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Вы можете создать вспомогательный метод для этого:

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 Это работает только для простых выражений без вложенных скобок.Вам нужно настроить, если вы ожидаете много сложных выражений.

0 голосов
/ 21 февраля 2019

Вы можете использовать границу слова (\b), чтобы избежать совпадения префиксов

Для указанного вами случая: следующее регулярное выражение будет соответствовать только KA или KARNATAKA

(\bKA\b|\bKARNATAKA\b)

Попробуйте здесь

...