Захват нескольких групп с помощью регулярных выражений - PullRequest
1 голос
/ 21 января 2020

У меня есть функция, которая находит одну группу, которая прекрасно работает

public static Optional<String> locateInText(String text, Pattern pattern) {
    Matcher matcher = pattern.matcher(text);
    return matcher.find() ? Optional.of(matcher.group(1)) : Optional.empty();
}

Теперь я пытаюсь создать функцию, которая находит 2 группы и объединяет их и возвращает значение в строке, если две группы не существует return 1 group

public static Optional<String> locateInTextt(String text, Pattern pattern) {
    Matcher matcher = pattern.matcher(text);
    while (matcher.find()) {
        if (matcher.groupCount() > 1) {
            int sum = Integer.parseInt(matcher.group(1)) + Integer.parseInt(matcher.group(2));
            return Optional.of(String.valueOf(sum));
        } else if (matcher.groupCount() == 1) {
            return Optional.of(matcher.group(1));
        }
    }
    return Optional.empty();
}

Тест сработал, если есть два совпадения, но если есть только одно, оно продолжает возвращаться пустым, то, что мне не хватает, я прочитал некоторую информацию, и это представляется возможным чтобы указать группу как необязательную, буду признателен за любой совет

Текст варианта использования:

Всего 2 Коробки, 193 Короб-шкафа

в этом случае, Мне нужно захватить обе группы, а это 2 и 193 = 195

Текст варианта второго использования

Всего 2 Коробки

Текст варианта третьего использования

Всего 193 Короб-шкафа

 Pattern.compile("Всего\\s*(\\d*)\\s*Коробки,\\s*([\\d,]*)\\s*(?:Короб-шкаф[ова]*|Коробо*к[аи]*)");

Ответы [ 2 ]

0 голосов
/ 21 января 2020

Это работает для вас? Я не использовал предоставленные вами методы, так как упомянутое вами требование basi c может быть достигнуто с помощью простого вызова Matcher.replaceAll().

Pattern p = Pattern.compile("Всего\\s*(\\d*)(\\s*Коробки,?)?(\\s*([\\d,]*)\\s*(?:Короб-шкаф[ова]*|Коробо*к[аи]*))?");
String replacement = "$1 $4";
String text = "Всего 2 Коробки, 193 Короб-шкафа";
System.out.println( p.matcher( text ).replaceAll( replacement ) );

При этом считается, что строка "Всего" присутствует в вход всегда.

0 голосов
/ 21 января 2020

в соответствии с вашим постом, вы хотите сопоставить строку и подстроки внутри, я не могу придумать правильного решения. Тем не менее, ваша проблема проста, если мы опускаем «Всего», то мы можем сделать следующее:

"((\\d*)\\s*Коробки|\\s*([\\d,]*)\\s*(?:Короб-шкаф[ова]*|Коробо*к[аи]*))"

, чтобы найти либо строку с «Коробки», либо другую строку

...