Регулярное выражение для запрета двух последовательных пробелов в середине строки

Мне нужно регулярное выражение для удовлетворения следующих требований:

  • Разрешены только буквы, точки и пробелы.
  • Нет пробела в начале и в конце строки.
  • Пробел в середине строки в порядке, но не два последовательных пробела.

Матчи:

"Hello world."
"Hello World. This is ok."

Не соответствует:

" Hello World. "
"Hello world 123." 
"Hello  world."

Это сработало в моем случае

<asp:RegularExpressionValidator ID="revDescription" runat="server" 
                                ControlToValidate="taDescription" Display="Dynamic" ErrorMessage="Invalid Description." 
                                Text="&nbsp" 
                                ValidationExpression="^(?i)(?![ ])(?!.*[ ]{2})(?!.*[ ]$)[A-Z. ]{8,20}$"></asp:RegularExpressionValidator>

2 ответа

Решение

Вот решение в Python, использующее якоря и отрицательные косвенные утверждения, чтобы обеспечить соблюдение правил пробелов:

regex = re.compile(
    """^          # Start of string
    (?![ ])       # Assert no space at the start
    (?!.*[ ]{2})  # Assert no two spaces in the middle
    (?!.*[ ]$)    # Assert no space at the end
    [A-Z. ]{8,20} # Match 8-20 ASCII letters, dots or spaces
    $             # End of string""", 
    re.IGNORECASE | re.VERBOSE)

Я бы посоветовал проверить длину вне регулярного выражения, иначе выражение может стать слишком сложным.

Вот пример фрагмента в JavaScript:

if (str.length < 8 || str.length > 20)
  return false;
if (str.match(/(^\s|\s$|\s\s|[^A-Za-z.\s])/))
  return false;

Регулярное выражение проверяет совпадение любого из запрещенных шаблонов:

  • ^\s пробел в начале
  • \s$ пробел в конце
  • \s\s два последовательных пробельных символа
  • [^A-Za-z.\s] символ, который не является буквой, точкой или пробелом

Если вы разрешите использовать только пробелы (ASCII 32), а не символы табуляции или другие пробельные символы, вы можете заменить все \s буквальным символом пространства.

Другим решением будет сочетание "положительного" выражения для проверки допустимых символов и длины и "отрицательного" выражения для исключения отклоненных шаблонов:

return str.match(/[A-Za-z. ]){8,20}/) && !str.match(/(^ | $|  )/);

Обновление: если вам нужно поместить все в одно выражение, я боюсь, что вы должны пропустить проверку последовательных пробелов, потому что это ограничение делает язык контекстно-зависимым, поэтому его нельзя проверить регулярным выражением. Что вы можете сделать, это проверить строку, начинающуюся с буквы, за которой следуют от 6 до 18 букв, точек или пробелов и заканчивающиеся буквой:

[A-Z][A-Z. ]{6,18}[A-Z]
Другие вопросы по тегам