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

#javascript #regex

#javascript #регулярное выражение

Вопрос:

У меня есть несколько тестовых строк:

  1. «x»
  2. «мм»
  3. «x mm»
  4. «гг х мм»
  5. «xx мм y мм»

Я хочу создать регулярное выражение, которое должно соответствовать строкам 1,2,3,4, но не 5.

Итак, мои ограничения для сопоставления следующие:

  1. Одна последовательность алфавитов должна встречаться в строке один раз. (например, «y» — это последовательность из одного y, а «yy» — это последовательность из двух y, но они содержат один и тот же алфавит, поэтому они противоречат друг другу и не могут встречаться вместе)
  2. В строке разрешены только определенные алфавиты (в моем случае «xym»).
  3. Любая последовательность может встречаться в начале, середине или конце строки. Но она должна иметь префикс или суффикс с символом, не являющимся словом, если другая последовательность алфавитов предшествует ей или следует за ней соответственно.
  4. Необязательно, чтобы в строке присутствовали все последовательности алфавитов.

Примечание: — Для решения этой проблемы мне нужно только одно регулярное выражение. Потому что с помощью отдельного регулярного выражения и итерации я уже сделал это. Я ищу однострочное решение для проверки моей строки.

Решение, которое я попробовал, это:

 /(?=^[xymW] $)((?=^([^m]*W)?m (W[^m]*)?$)|(?=^([^x]*W)?x (W[^x]*)?$)|(?=^([^y]*W)?y (W[^y]*)?$))/
  

Но это также соответствует 5-му случаю.

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

1. Итак, проблема с пятым примером заключается в том, что mm он появляется дважды, а не в том, что в нем четыре последовательности?

2. Может ли последовательность смешивать символы? "xy mx" Допустимо?

3. @T.J. Crowder да

4. Хорошо. Пожалуйста, обновите вопрос всеми этими. Обратите внимание, что «y» — это не последовательность , это буква (символ). Это важно для наглядности, потому что «y» и «yy» — это разные последовательности , но они используют одну и ту же букву.

5. Попробуйте /^(?!.*b([xym])1*b.*b1 b)s*[xyms] s*$/ , посмотрите демо .

Ответ №1:

Вы можете использовать

 /^(?!.*b([xym])1*b.*b1 b)(?:s*b([xym])2*b)*s*$/
  

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

Подробные сведения

  • ^ — начало строки
  • (?!.*b([xym])1*b.*b1 b) — отрицательный прогноз, при котором совпадение не выполняется, если сразу после начала строки
    • .* — любые символы 0 , отличные от символов разрыва строки, как можно больше
    • b([xym])1*b — целое слово, состоящее из идентичных символов, x , y или m
    • .* — любые символы 0 , отличные от символов разрыва строки, как можно больше
    • b1 b — целое слово, состоящее из символа, захваченного в группе 1
  • (?:s*b([xym])2*b)* — 0 или более повторений
    • s* — 0 или более символов пробела
    • b([xym])2*b — целое слово, состоящее из 1 или более одинаковых символов, x , y или m
  • s* — 0 или более символов пробела
  • $ — конец строки.

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

1. В этом случае произошел сбой, последовательность символов «ммм гггг xxyyyyx» должна содержать одинаковые символы.

2. @RK_15 ^(?!.*b([xym])1*b.*b1 b)(?:s*b([xym])2*b)*s*$

3. В этом случае произошел сбой «mmmyy yyy xxx»

4. @RK_15 есть нет совпадений по mmmyy yyy xxx , не так ли ожидать? yy повторяется

5. Я не пробовал использовать веб-сайт Regex101, но в консоли Chrome это утверждение возвращает false -> /^(?!.* b([xym])1*b.*b1 b)(?:s*b([xym])2*b) *s*$/.test(«mmmyy yyy xxx»)