Дополнительная группа захвата Regex?
После нескольких часов поиска я решил задать этот вопрос. Почему это регулярное выражение: ^(dog).+?(cat)?
не работает, поскольку я думаю, что он должен работать (захватить первую собаку и кошку, если она есть)? Что мне здесь не хватает?
dog, cat
dog, dog, cat
dog, dog, dog
Ответы
Ответ 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))?
Снова, здесь расширенная демонстрация и регулярное выражение.