#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/13. Разделите проверяемую строку на любой отдельный пробел и проверьте длину результирующего массива. Например,
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] $/
^ ^ ^^
Итак,
s
добавляется к выражению, чтобы оно могло соответствовать пробелам(?!(?:S*s){3})
гарантирует, что в строке не будет трех или более пробелов (между ними могут быть любые символы, не содержащие пробелов, благодаряS*
).
Еще кое-что нужно учитывать
Чтобы запретить пробелы в начале и в конце, добавьте больше просмотров
/^(?!s)(?!.*s$)(?!(?:S*s){3})[a-zA-Zsu00c4u00e4u00d6u00f6u00dcu00fcu00df] $/
^ ^
Также запретить последовательные пробелы
/^(?!s)(?!.*s$)(?!.*s{2})(?!(?:S*s){3})[a-zA-Zsu00c4u00e4u00d6u00f6u00dcu00fcu00df] $/
^ ^