Подтвердить что ты не робот

Дополнительная группа захвата Regex?

После нескольких часов поиска я решил задать этот вопрос. Почему это регулярное выражение: ^(dog).+?(cat)? не работает, поскольку я думаю, что он должен работать (захватить первую собаку и кошку, если она есть)? Что мне здесь не хватает?

dog, cat
dog, dog, cat
dog, dog, dog
4b9b3361

Ответ 1

Причина, по которой вы не получаете необязательный cat после неохотно-квалифицированного .+?, состоит в том, что он является необязательным и не привязанным: движок не вынужден делать это совпадение, поскольку он может легально лечить cat как "хвост" последовательности .+?.

Если yo привязать кошку к концу строки, т.е. использовать ^(dog).+?(cat)?$, вы получите совпадение:

Pattern p = Pattern.compile("^(dog).+?(cat)?$");
for (String s : new String[] {"dog, cat", "dog, dog, cat", "dog, dog, dog"}) {
    Matcher m = p.matcher(s);
    if (m.find()) {
        System.out.println(m.group(1)+" "+m.group(2));
    }
}

Отправляет (демонстрация 1)

dog cat
dog cat
dog null

Вы знаете, как с этим справиться, если есть что-то после кошки?

Вы можете справиться с этим, создав более сложное выражение, которое соответствует чему-либо, кроме cat, например:

^(dog)(?:[^c]|c[^a]|ca[^t])+(cat)?

Теперь cat может произойти где угодно в строке без привязки (demo 2).

Ответ 2

@dasblinkenlight ответ велик, но вот регулярное выражение, которое улучшает вторую часть, когда он/она спрашивает

Вы знаете, как с этим справиться, если есть что-то после кошки?

Регулярное выражение ^(dog)(.+(cat))? потребует, чтобы вы записали номер группы. 3 вместо 2, чтобы получить дополнительную кошку, но работает так же, как без char -by- char.

И здесь демонстрация (которая опять же разветвлена ​​из демонстрации @dasblinkenlight, которая позволила мне возиться и найти это решение, еще раз спасибо!)

Ответ 3

Расширение @figha может быть еще немного расширено, чтобы не сделать ненужный второй захват.

Используйте ?:, чтобы заключить в скобки часть регулярного выражения, которое не было захвачено. Поэтому регулярное выражение становится: ^(dog)(?:.+(cat))?

Снова, здесь расширенная демонстрация и регулярное выражение.