Движки Regex не сдаются в матче, пока не попробуют все возможности.
В вашем регулярном выражении эта последовательность .{0,50}?
будет соответствовать не жадно, от 0 до 50 символов.
В своем примере regex101 вы указали модификатор Dot-all // s, что означает, что ваша точка будет охватывать линии.Так уж получилось, что на следующей строке он может удовлетворить тело (контент), где (?! \ S * [/ code]) проходит.
Вы заметите, что для этого кавычка отбрасывается в обратном направлении, так что ( ["']? )
никогда не совпадает, а \1
- просто пустая строка.Это оставляет дверь открытой для не жадной последовательности, чтобы стать жадной.Это момент GOTCHA.
Обновление
После дальнейшего рассмотрения я твердо верю, что есть только 1 способ
, чтобы удовлетворить все условия, чтобы сделать это регулярное выражение.
Шаги:
Обернуть часть цитаты вокруг атомной группы.
Это делает эту частьматч непроницаемый для возврата.
Используйте чередование, чтобы различать указанное в кавычках значение или не заключенное в кавычки.
Сначала поставить цитируемую часть.
Обратите внимание, что вы вообще не можете использовать отрицательный класс внутри цитируемой части (т. Е. [^\[\]]
), поскольку идея цитаты состоит в том, чтобы разрешать такие разделители, как []
.
Эта часть должна пассивно разрешать любыесимвол .
.
Это позволит сопоставить строку, подобную этой
[code="t][/code]"]hello world[/code]
, однако невероятная генерация такой строки может быть .
И это все.Если это сделано любым другим способом, это просто неправильно.
Я включаю ссылку, которая показывает все возможные случаи.
Если вы обнаружите ошибку ... ах, ее нет.
Группы 2 и 3 содержат значения (одно или другое), просто объедините
их.
Группа 4 содержит содержимое.
(?s)\[code(?>(?:=(?:(["'])(.{0,50}?)\1|([^\]]{0,50})))?)\](?!\s*\[\/code\])(.*?)\[\/code\]
https://regex101.com/r/cO73iA/1
Объяснено
(?s) # Dot-all modifier
\[code # Open bbcode tag
(?> # Atomic group, can't be backtracked into
(?:
=
(?:
( ["'] ) # (1), Quote
( .{0,50}? ) # (2), code value
\1 # Backref to Quote
| # or,
( [^\]]{0,50} ) # (3), Un-quoted code value
)
)?
)
\]
(?! \s* \[/code\] ) # Cannot be empty content
( .*? ) # (4), Content, must be some
\[/code\] # Close bbcode tag