RegExp. Разрешить только один разделитель в тексте при двух возможных вариантах
Была задача запретить использовать два разделителя подряд при заполнении текстового поля в форме. При этом разделителем может служить как пробел, так и дефис.
Написал так:
^(?!.*\-$)(?!.*([\-\s])\1)(.)+$
И в таком случае, регулярное выражение не пропускает текст если поставить два дефиса или два пробела подряд, но пробел и дефис или дефис и пробел вместе - пропускает.
Как в данном выражении запретить использовать пробел и дефис вместе?
https://regex101.com/r/XKnAj0/2
Ответы (2 шт):
Дело в том, что ([\-\s])\1 находит двойной дефис или пробельный символ, так как первый символ захватывается в подмаску №1, а обратная ссылка \1 находит именно такой же символ.
Вам нужно просто повторить поиск дефиса либо пробельного символа, [-\s][-\s], или [-\s]{2} или ([-\s])(?1) ((?1) повторяет шаблон первой захватывающей подмаски, здесь использовать не советую, просто для иллюстрации возможностей библиотеки PCRE).
Используйте
^(?!.*[-\s][-\s]).*[^-]$
^(?!.*[-\s]{2}).+$(?<!-)
См. пример работы выражения. Экранировать дефис в начальной позиции в символьных классах не требуется.
Подробности
^- начало строки(?!.*[-\s]{2})- блок предварительного просмотра вперёд, который отменяет совпадение, если сразу справа от текущей позиции есть 0 и более символов, отличных от перевода строки, как можно больше, а потом два пробельных символа или дефиса.*- 0 и более символов, отличных от перевода строки, как можно больше.+- 1 и более символов, отличных от перевода строки, как можно больше[^-]- любой символ кроме-$- конец строки(?<!-)- блок предварительного просмотра назад, который отменяет совпадение, если сразу слева от текущей позиции есть-.