Регулярное выражение Javascript — только 0-2 пробела или дефиса во всей строке?

#javascript #regex #string #limit #spaces

#javascript #регулярное выражение #строка #ограничение #пробелы

Вопрос:

У меня есть следующее простое регулярное выражение:
/^[a-zA-Zu00c4u00e4u00d6u00f6u00dcu00fcu00df] $/

я хотел бы сделать возможным наличие строк типа «Blabla Bla bshfkhsf». Но во всей строке не должно быть более 2 пробелов или дефисов.

Я знаю, что я могу ограничить пробелы с помощью » s {0,2}», но как мне установить такое ограничение в регулярном выражении, чтобы были возможны строки, подобные приведенным выше, и ограничение применялось ко всей строке, а не к «одиночному» символу?

РЕДАКТИРОВАТЬ: может ли это быть нормально:

 ^[a-zA-Zu00c4u00e4u00d6u00f6u00dcu00fcu00df] ((s)|(-))?[a-zA-Zu00c4u00e4u00d6u00f6u00dcu00fcu00df] ((s)|(-))?[a-zA-Zu00c4u00e4u00d6u00f6u00dcu00fcu00df] $
  

Есть ли лучший способ?

Комментарии:

1. Более 2 пробелов в целом или в последствии? Например, 'a a a' нормально?

2.При необходимости повторите всю часть 0 — 2 раза и используйте класс символов [s-] для сопоставления с символом дефиса или пробела ^[a-zA-Zu00c4u00e4u00d6u00f6u00dcu00fcu00df] (?:[s-][a-zA-Zu00c4u00e4u00d6u00f6u00dcu00fcu00df] ){0,2}$ regex101.com/r/NPOx7h/1

3. Разделите проверяемую строку на любой отдельный пробел и проверьте длину результирующего массива. Например, sampleText.split(/s/).length <= 3 было ли условие тестирования строки, которое соответствует требованиям вашего Q.

4. @raina77ow: только один пробел между символами (словами). Thefourthbird: {0,2} в конце тоже не для символов? ПетерСелигер: Да, я знаю, что я просто могу посчитать пробелы, но это не так элегантно. РЕДАКТИРОВАТЬ: Хорошо, Thefourthbird, я понимаю…

5. Почему это - в вашем шаблоне? Должно - быть тоже покрыто?

Ответ №1:

Если вы не хотите сопоставлять только пробелы, вы можете сопоставить первую часть, а затем использовать квантификатор {0,2} , чтобы повторить всю часть снова, перед которой стоит символьный класс [s-] , чтобы сопоставить либо символ пробела, либо дефис.

Если это должен быть только символ пробела, вы можете использовать простой s символ (который также может соответствовать новой строке)

Обратите внимание, что в вашем шаблоне все чередование ((s)|(-))? является необязательным, поэтому минимальная длина одного совпадения в этом случае будет составлять 3 символа. Смотрите этот пример.

Вы могли бы обновить шаблон до

 ^[a-zA-Zu00c4u00e4u00d6u00f6u00dcu00fcu00df] (?:[s-][a-zA-Zu00c4u00e4u00d6u00f6u00dcu00fcu00df] ){0,2}$
  

Объяснение

  • ^ Начало строки
  • [a-zA-Zu00c4u00e4u00d6u00f6u00dcu00fcu00df] Сопоставьте 1 раз любой из перечисленных
  • (?: Не группа захвата
    • [s-] Сопоставьте либо символ пробела, либо -
    • [a-zA-Zu00c4u00e4u00d6u00f6u00dcu00fcu00df] Сопоставьте 1 раз любой из перечисленных
  • ){0,2} Закройте группу и повторите ее 0-2 раза
  • $ Конец строки

Смотрите демонстрацию регулярных выражений

Комментарии:

1. Что [s-] должно означать?

2. @raina77ow Это класс символов, который соответствует одному из перечисленных символов.

3. Ах да, код, заданный OP, действительно имеет этот дефис. Это противоречит сообщению OP (- не является пробелом), но я понимаю вашу точку зрения здесь.

4. Спасибо за ответ. Я уже понял, но спасибо и за объяснение.

Ответ №2:

Вместо того, чтобы повторять весь класс символов, вы можете просто использовать lookahead для объединения условий:

 /^(?=[^s-]*([s-][^s-]*){0,2}$)[a-zA-Zu00c4u00e4u00d6u00f6u00dcu00fcu00dfs-] $/
  

Демонстрация регулярного выражения 101. По сути, это два регулярных выражения в одном:

 (?=[^s-]*([s-][^s-]*){0,2}$)
  

Эта часть проверяет, удовлетворяет ли целая строка правилу «не более 2 пробелов или — символов».

 [a-zA-Zu00c4u00e4u00d6u00f6u00dcu00fcu00dfs-] $
  

Эта часть проверяет, удовлетворяет ли вся строка правилу «только буквы, пробелы и дефисы». Дело в том, что весь шаблон совпадает только в том случае, если обе проверки пройдены.

Комментарии:

1. Хм. Звучит хорошо, но я не понимаю первую часть.

2. Что именно неясно? Вы знаете, как работает lookahead?

3. Нет, я впервые слышу о lookahead. Должен прочитать об этом…

4. Это нормально, живи и учись. 🙂 Использование предвидений описанным способом позволяет нам объединить несколько условий, которые в противном случае было бы неудобно объединять в шаблон.

5. Спасибо за ответ и объяснение. Похоже, что это «самый умный» способ, даже если он больше похож на иероглифы, чем на другой ответ 😉

Ответ №3:

Перефразируя ваше требование, вам нужно сопоставить строку, в которой не может быть трех или более пробелов.

Использовать

 /^(?!(?:S*s){3})[a-zA-Zsu00c4u00e4u00d6u00f6u00dcu00fcu00df] $/
  ^              ^       ^^
  

Итак,

  1. s добавляется к выражению, чтобы оно могло соответствовать пробелам
  2. (?!(?:S*s){3}) гарантирует, что в строке не будет трех или более пробелов (между ними могут быть любые символы, не содержащие пробелов, благодаря S* ).

Еще кое-что нужно учитывать

Чтобы запретить пробелы в начале и в конце, добавьте больше просмотров

 /^(?!s)(?!.*s$)(?!(?:S*s){3})[a-zA-Zsu00c4u00e4u00d6u00f6u00dcu00fcu00df] $/
  ^             ^
  

Также запретить последовательные пробелы

 /^(?!s)(?!.*s$)(?!.*s{2})(?!(?:S*s){3})[a-zA-Zsu00c4u00e4u00d6u00f6u00dcu00fcu00df] $/
                 ^         ^