Отрицательный взгляд сзади и квадратные скобки

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

]ichael ==> match ]

[my name is Michael] ==> no match

В моем тексте нет вложенных пар квадратных скобок.

Я попытался использовать отрицательный взгляд назад для этого, более конкретно я использую это регулярное выражение: (?<!\[(.)+)\] но, похоже, это не сработало.

Какие-либо предложения?

4 ответа

Если вы не используете.NET, внешний вид должен быть фиксированной длины. Так как вы просто хотите определить, есть ли какие-либо непревзойденные закрывающие скобки, вам на самом деле не нужен просмотр сзади:

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

Если это соответствует, у вас есть непревзойденная закрывающая скобка.

Это немного легче понять, если вы понимаете, что [^\[\]] является классом отрицанных символов, который соответствует чему угодно, кроме квадратных скобок, и если вы разместите его в свободном режиме:

^              # start from the beginning of the string
[^\[\]]*       # match non-bracket characters
(?:            # this group matches matched brackets and what follows them
  \[           # match [
  [^\[\]]*     # match non-bracket characters
  \]           # match ]
  [^\[\]]*     # match non-bracket characters
)*             # repeat 0 or more times
\]             # match ]

Так что это пытается найти ] после сопоставления 0 или более согласованных пар скобок.

Обратите внимание, что часть между ^ а также ] функционально эквивалентен решению Тима Пицкера (которое, я думаю, немного легче понять концептуально). То, что я сделал, - это метод оптимизации, который называется "развертывание цикла". Если ваш аромат обеспечивает притяжательные квантификаторы, вы можете включить все * в *+ повысить эффективность еще дальше.


О вашей попытке

Даже если вы используете.NET, проблема с вашим шаблоном заключается в том, что . позволяет пройти мимо других скобок. Следовательно, вы не получите соответствия в

[abc]def]

Потому что и первое, и второе ] иметь [ где-то перед ними. Если вы используете.NET, самое простое решение

(?<!\[[^\[\]]*)\]

Здесь мы используем символы без скобок в повторении, чтобы мы не смотрели мимо первого [ или же ] мы сталкиваемся слева.

Вам вообще не нужен обходной путь (и было бы трудно использовать его в большинстве языков, не допускающих неограниченного просмотра утверждений):

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

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

Часть перед ] можно найти в $1 так что вы можете использовать его позже.

Объяснение:

(           # Match and capture in group number 1:
 (?:        # the following regex (start of non-capturing group):
  \[        # Either a [
  [^\[\]]*  # followed by non-brackets
  \]        # followed by ]
 |          # or
  [^\[\]]*  # Any number of non-bracket characters
 )*+        # repeat as needed, match possessively to avoid backtracking
)           # End of capturing group
\]          # Match ]

Это должно сделать это:

'^[^\[]*\]'

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

\](.*)

Будет соответствовать всем после ]:

]ichael -> ichael
[my name is Michael] ->
Другие вопросы по тегам