Отрицательный взгляд сзади и квадратные скобки
Я хотел бы создать регулярное выражение, которое соответствует непревзойденным квадратным скобкам. Примеры:
]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] ->