RegEx в JS, чтобы найти 3 одинаковых последовательных символа

Как найти последовательность из 3 символов, «abb» действителен, а «abbb» недействителен, в JS с использованием Regex (могут быть алфавиты, цифры и не буквенно-цифровые).

Этот вопрос является вариантом вопроса, который я задал здесь: >Как объединить эти регулярные выражения для javascript.

Это неправильно: /(^([0-9a-zA-Z]|[^0-9a-zA-Z]))\1\1/, так как же правильно это сделать?


person Nohsib    schedule 27.10.2012    source источник
comment
Нет, он хочет противоположного этому   -  person Martin Ender    schedule 27.10.2012
comment
@m.buettner Я вижу, пропустил Нет, который я прочитал как сокращение от номера   -  person Prinzhorn    schedule 27.10.2012
comment
дубликат? stackoverflow.com/questions/8880088/   -  person Gurpreet Singh    schedule 27.10.2012
comment
@GurpreetSingh, я так не думаю. Вопрос, который вы связали, касается конкретно последовательных символов   -  person Martin Ender    schedule 27.10.2012
comment
@ m.buettner Я перефразировал первое предложение. Будем надеяться, что мои правки доживут до этого времени...   -  person Prinzhorn    schedule 27.10.2012
comment
@Prinzhorn, спасибо, одобрено;)   -  person Martin Ender    schedule 27.10.2012


Ответы (2)


Это зависит от того, что вы на самом деле имеете в виду. Если вы хотите сопоставить только три неидентичных символа (то есть, если abb допустимо для вас), вы можете использовать этот отрицательный просмотр вперед:

(?!(.)\1\1).{3}

Сначала он утверждает, что за текущей позицией не следует три раза один и тот же символ. Тогда он соответствует этим трем символам.

Если вы действительно хотите сопоставить 3 разных символа (только такие вещи, как abc), это становится немного сложнее. Вместо этого используйте эти два отрицательных прогноза:

(.)(?!\1)(.)(?!\1|\2).

Сначала сопоставьте один символ. Затем мы утверждаем, что за этим не следует тот же символ. Если это так, мы сопоставляем другой символ. Тогда мы утверждаем, что за ними не следует ни первый, ни второй символ. Затем мы сопоставляем третий символ.

Обратите внимание, что эти отрицательные прогнозы ((?!...)) не потребляют никаких символов. Вот почему они называются упреждающими. Они просто проверяют, что будет дальше (или, в данном случае, что не будет дальше), а затем регулярное выражение продолжится с того места, где оно осталось. Вот хорошее руководство.

Также обратите внимание, что это соответствует чему угодно, кроме разрывов строк, или действительно что угодно, если вы используете параметр DOTALL или SINGLELINE. Поскольку вы используете JavaScript, вы можете просто активировать эту опцию, добавив s после закрывающего разделителя регулярных выражений. Если (по какой-то причине) вы не хотите использовать эту опцию, замените .s на [\s\S] (это всегда соответствует любому символу).

Обновление:

После пояснений в комментариях я понял, что вы не хотите находить три неидентичных символа, а вместо этого хотите утверждать, что ваша строка не содержит три одинаковых (и последовательных) символа.

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

^(?!.*(.)\1\1)

Упреждающий просмотр привязан к началу строки, так что это единственное место, куда мы будем смотреть. Затем шаблон в предварительном просмотре пытается найти три одинаковых символа из любой позиции в строке (из-за .*; идентичные символы сопоставляются так же, как и в вашем предыдущем вопросе). Если шаблон обнаружит их, отрицательный просмотр не удастся, и строка будет недействительной. Если не удается найти трех одинаковых символов, внутренний шаблон никогда не совпадет, поэтому отрицательный просмотр будет успешным.

person Martin Ender    schedule 27.10.2012
comment
спасибо за ответы с такой ясностью. В моем случае «abb» допустимо, а «abbb» — нет. Это '(?!(.)\1\1).{3}' возвращает true даже для 'abbb' - person Nohsib; 29.10.2012
comment
Ах хорошо. Я думал, вы хотите найти 3 неидентичных символа в своей строке. Но вы хотите утверждать, что в вашей строке никогда не бывает трех одинаковых символов. Тогда я отредактирую свой ответ. - person Martin Ender; 29.10.2012

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

([\s\S])(?!\1\1)[\s\S]{2}
person Ωmega    schedule 27.10.2012
comment
Ну, тогда моего английского, наверное, не хватает, чтобы уловить эти нюансы. Я думал, что все три должны отличаться друг от друга. - person Prinzhorn; 27.10.2012
comment
@Prinzhorn, английский язык или, по крайней мере, формулировка ОП в этом случае были довольно двусмысленными. Но есть конечно разница не три одинаковых, а три не одинаковых (abb vs abc). - person Martin Ender; 27.10.2012