Regex, чтобы разрешить все символы, кроме повторов конкретного данного символа - PullRequest
1 голос
/ 30 июня 2011

Я немного возился с этим и думал, что передам это экспертам по регулярным выражениям:

Я хочу сопоставить строки следующим образом:

abc[abcde]fff
abcffasd

, поэтому я хочу использовать одинарные скобки (например, [ или ]). Однако я не хочу разрешать двойные скобки в последовательности (например, [[ или ]]).

Это означает, что эта строка не должна проходить регулярное выражение:

abc[abcde]fff[[gg]]

Мое лучшее предположение на данный момент основано на примере, который я нашел , что-то вроде:

(?>[a-zA-Z\[\]']+)(?!\[\[)

Однако, это не работает (оно совпадает, даже если присутствуют двойные скобки), возможно потому, что скобки также содержатся в первой части.

Ответы [ 4 ]

2 голосов
/ 01 июля 2011

Вы можете попробовать этот негативный взгляд:

$arr = array('abc[abcde]fff', 'abcffasd', 'abc[abcde]fff[[gg]]');
foreach ($arr as $str) {
   echo $str,' => ';
   $ret = preg_match('/^(?!.*?(\[\[)).+$/', $str, $m);
   echo "$ret\n";
}

OUTPUT

abc[abcde]fff => 1
abcffasd => 1
abc[abcde]fff[[gg]] => 0
2 голосов
/ 30 июня 2011

Не подлежит удержанию!

^(?:(?:[a-z]+)|(?:\](?!\]))|(?:\[(?!\[)))+$

Я убрал только две или более вещи.Я удалил избыточные классы символов только для одного символа.Кажется, это проходит все тестовые случаи, о которых я могу думать.Любая строка символов, содержащая только один [ или ].

Дайте мне знать, если это работает для вас!


Я не уверен, что могу ответить на этот вопрос, ноЯ опубликую то, что у меня есть, по мере того, как я прохожу это.

Во-первых, у меня есть это, которое, кажется, соответствует без скобок.Это любая буква, за которой не следует 2 или более.

 ^(?:([a-z])(?!\1{2,}))+$

Мы можем добавить скобки в класс символов, и он начнет совпадать с скобками;но, очевидно, это также позволит им следовать тем же правилам, что и буквы (два вместе действительны).Как отделить поведение скобок от поведения букв?

 ^(?:([a-z\[\]])(?!\1{2,}))+$

Это выглядит грязно, но, похоже, работает.Глядя на другой ответ, мне это нравится намного лучше.Теперь, чтобы понять, почему я не подумал об этом.

^(?:(?:([a-z])(?!\1{2,}))|(?:[\]](?![\]]))|(?:[\[](?![\[])))+$

Кроме того, по какой-то причине я подумал, что это 1-2 символа, но только один из [ и ], так чтовсе равно ничего не стоит :).

2 голосов
/ 01 июля 2011

Вы хотите что-то вроде:

^(?:\[?[^\[]|\[$)*$

В каждом символе шаблон принимает открывающую скобку, за которой следует другой символ или конец строки.

Или чуть более аккуратно, используя отрицательный взгляд :

^(?:(?!\[\[).)*$

Здесь шаблон будет соответствовать только символам до тех пор, пока он не увидит два [[ впереди.

0 голосов
/ 30 июня 2011

Это регулярное выражение должно содержать все буквы и скобки, кроме двух последовательных скобок (т. Е. [], [[Или]])

([a-zA-Z\[\]][a-zA-Z])+

РЕДАКТИРОВАТЬ: Извините, это не будет работать для строк с нечетной длиной

...