Как правильно настроить работу групп захвата в регулярном выражении?
Пытаюсь составить регулярное выражение, состоящее из трех групп.
1 группа - набор команд (обязательно надо вводить)
2 группа - номер события (необязательно вводить)
3 группа - событие (необязательно вводить).
Вот мое выражение:
(\s*^add|list|edit\b)(\s+\d*)(\s*.*).
Ввод первой группы (команда) не определяется, пока не поставлю пробел в конце после ввода, а если ввести пробел, то первая группа определяется, НО возникает проблема при компиляции: NumberFormatException: For input string: " 4".
Я так понимаю, это из-за пробела?
Ответы (1 шт):
Напишу ответом:
Предложенный вами вариант: (\s*^add|list|edit\b)(\s+\d*)(\s*.*)
- Указан
\s- может произойти захват новой строки, нарушив при этом цепочку значений, в случае если в строке к примеру не указан комментарий \b- установлено только для edit, остальные add, list, идут без границы слова, хотя по факту тут эта граница и не нужна, но если ее все же нужно использовать, то лучше вынести за пределы первой группы(\s*^add|list|edit)\b- Вторая группа
(\s+\d*)описывает обязательное(квантификатор+) наличие одного и более пробелов и необязательного(квантификатор*) появления одной и более цифр. Правильнее было бы описать данный шаблон отделив пробельные символы от захвата, что бы не записывать получившиеся пробелы и сделать группу необязательной исходя из условия. Группы поддерживают квантификаторы, поэтому указать второй группе захвата квантификатор?и привести к виду(?:[ \t]+(\d+))?, где?:означает, что группа не подлежит групповому захвату, она нам нужна только для проверки, обязательное появление одного и более пробела или символа табуляции и обязательное появление одной и более цифры, которые мы ставим в группу захвата, это как раз и будет второй группой. Завершаем не захватываемую группу указанием квантификатора?означающего ноль или одно совпадение. - Третья группа в вашем примере захватывает ноль и более пробельных символов и далее ноль и более любых символов. Схема в данном случае будет аналогична второй группе
(?:[ \t]+(.+))?
Итого, получаем примерно такой шаблон, в данном случае захват события будет всегда в третьей группе, а захват номера события во второй, даже если не указан номер события, а только событие.
^(add|list|edit)(?:[ \t]+(\d+))?(?:[ \t]+(.+))?$
Под данный шаблон будут подходить следующие строки:
add 12 Какой то комментарий
list 54345
edit Какой то комментарий
list
и подобные.
Если нужно будет исключить пробельные символы для захвата групп из строк типа:
list12комментарий какой-то
то в шаблоне следует поменять квантификаторы на захват пробельных символов:
^(add|list|edit)(?:[ \t]*(\d+))?(?:[ \t]*(.+))?
________________________^_______________^______
указав необязательное появление.
Попробовать и настроить шаблон регулярного выражения можно к примеру тут:
https://regex101.com/r/A9xHGx/1