Шаблон регулярных выражений для коротких кодов в PHP
У меня проблема с регулярным выражением, которое я написал, чтобы соответствовать коротким кодам в PHP.
Это шаблон, где $shortcode
- название шорткода:
\[$shortcode(.+?)?\](?:(.+?)?\[\/$shortcode\])?
Теперь это регулярное выражение довольно хорошо работает с этими форматами:
[shortcode]
[shortcode=value]
[shortcode key=value]
[shortcode=value]Text[/shortcode]
[shortcode key1=value1 key2=value2]Text[shortcode]
Но, похоже, у него проблемы с наиболее распространенным форматом,
[shortcode]Text[/shortcode]
, который возвращает, как соответствует следующее:
Array
(
[0] => [shortcode]Text[/shortcode]
[1] => ]Text[/shortcode
)
Как вы можете видеть, второе совпадение (которое должно быть текстом, так как первое необязательно) включает конец открывающего тега и весь закрывающий тег, кроме последней скобки.
РЕДАКТИРОВАТЬ: Обнаружил, что возвращенное совпадение является первым захватом, а не вторым. Смотрите регулярное выражение в Регулярном выражении.
Не могли бы вы помочь с этим, пожалуйста? Я действительно ломаю себе голову над этим.
2 answers
В вашем регулярном выражении:
\[$shortcode(.+?)?\](?:(.+?)?\[\/$shortcode\])?
Первая группа захвата (.+?)
соответствует по крайней мере 1 символу.
Вся группа необязательна, но в данном случае она совпадает со всеми вещами до последнего ]
.
Работает следующее регулярное выражение:
\[$shortcode(.*?)?\](?:(.+?)?\[\/$shortcode\])?
Квантор *
означает 0 или более, в то время как +
означает один или несколько.
Конечно, это из C#, но
@"\[([\w-_]+)([^\]]*)?\](?:(.+?)?\[\/\1\])?"
Должен соответствовать любому (?), возможно, самозакрывающемуся шорткоду.
Или вы можете украсть из wordpress: https://core.trac.wordpress.org/browser/tags/4.0/src/wp-includes/shortcodes.php#L309
$pattern = '/(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*\'([^\']*)\'(?:\s|$)|(\w+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/';
$text = preg_replace("/[\x{00a0}\x{200b}]+/u", " ", $text);
if ( preg_match_all($pattern, $text, $match, PREG_SET_ORDER) )...