WordPress: проблема с регулярным выражением шорткода - PullRequest
1 голос
/ 02 апреля 2010

Это регулярное выражение, используемое для «коротких кодов» в WordPress (одно для целого тега, другое для атрибутов).

return '(.?)\[('.$tagregexp.')\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?(.?)';
$pattern = '/(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*\'([^\']*)\'(?:\s|$)|(\w+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/';

Он разбирает такие вещи, как

[foo bar="baz"]content[/foo]

или

[foo /]

В треке WordPress говорят, что это немного ошибочно, но моя главная проблема в том, что он не поддерживает шорткоды внутри атрибутов, как в

[foo bar="[baz /]"]content[/foo]

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

[foo bar="[baz /]

и

"]content[/foo]

показывает как есть.

Есть ли способ изменить регулярное выражение, чтобы оно могло обойти любое вхождение [ с ] и его содержимое, когда происходит между открывающим тегом или самозакрывающимся тегом?

Ответы [ 5 ]

0 голосов
/ 27 октября 2010

Это было бы неплохо исправить!У меня нет достаточного количества представителей, чтобы комментировать, поэтому я оставляю следующую связанную ссылку WordPress Trac, возможно, она совпадает с той, что вы имели в виду: http://core.trac.wordpress.org/ticket/14481

Я надеюсь, что любое исправление разрешит синтаксис шорткодакак

[shortcode att1 = "val] ue"] content [/ shortcode]

, поскольку в версии 3.0.1 содержимое $ неправильно обрабатывается как ue"]content вместо * content

Обновление : потратив время на изучение правил (регулярных выражений?), Я позволил разрешить] и экранированные кавычки в стиле Паскаля (например, arg = 'that' [так] здорово') в этих аргументах с 2 изменениями: сначала измените группу (.*?) в первом регулярном выражении (get_shortcode_regex) на

((?:[^'"\]]|'[^']*'|"[^"]*")*)

(NB: убедитесь, что вы все правильно экранировали в своем php-коде), затемв shortcode_parse_atts (функция, содержащая второе регулярное выражение) измените следующее (опять же, измените ' на \', если в одинарных кавычках $pattern как в исходном коде)

in $pattern change "([^"]*)" to "((?:[^"]|"")*)"
in $pattern change '([^']*)' to '((?:[^']|'')*)'
$atts[strtolower($m[1])] = preg_replace('_""_', '"', stripcslashes($m[2]));
$atts[strtolower($m[3])] = preg_replace("_''_", "'", stripcslashes($m[4]));

NBеще раз: изменения в шаблоне могут основываться на жадном характере соответствия, так что если этот параметр когда-либозависание, измененные биты $pattern могут заканчиваться чем-то вроде (?!") и т. д.

0 голосов
/ 15 апреля 2010

Я нашел способ это исправить: Во-первых, измените регулярное выражение шорткода с:

(.?)\[('.$tagregexp.')\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?(.?)

Кому:

(.?)\[('.$tagregexp.')\b((?:[^\[\]]|(?R)|.)*?)(?:(\/))?\](?:(.+?)\[\/\2\])?(.?)

А затем измените приоритет функции do_shortcode, чтобы избежать конфликта с wptexturize, функцией, которая стилизует кавычки и портит это исправление. У него нет проблем с wpautop, потому что это несколько исправлено с другой недавней функцией, я думаю.

До:

add_filter('the_content', 'do_shortcode', 11); // AFTER wpautop() 

После того, как:

add_filter('the_content', 'do_shortcode', 9);  

Я отправил это в трак, и у меня какой-то постоянный перерыв. Тем временем я понимаю, смогу ли я создать плагин, чтобы применить моё исправление без изменения файлов ядра. Переопределить приоритет фильтра легко, но я понятия не имею, как переопределить регулярное выражение.

0 голосов
/ 02 апреля 2010
return '(.?)\[('.$tagregexp.')\b((?:"[^"]*"|.)*?)(?:/)?\](?:(.+?)\[\/\2\])?(.?)';

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

(?:"[^"]*"|.)*?

вместо

.*?

Обратите внимание, что он не обрабатывает строки с экранированными кавычками в них (пока - может быть сделано, но нужно ли это?). Я ничего не изменил, потому что не знаю синтаксис шорткодов WordPress.

Но похоже, что его можно было немного очистить, удалив ненужные обратные слеши и скобки:

return '(.?)\[(foo)\b((?:"[^"]*"|.)*?)/?\](?:(.+?)\[/\2\])?(.?)';

Возможно, необходимы дальнейшие улучшения. Я немного обеспокоен неточной точкой в ​​приведенном выше фрагменте, и я предпочел бы использовать (?:"[^"]*"|[^/\]])* вместо (?:"[^"]*"|.)*?, но я не знаю, сломает ли это что-то еще. Кроме того, я не знаю, для чего хороши ведущий и трейлинг (.?). Они не соответствуют ничему в вашем примере, поэтому я не знаю их цели.

0 голосов
/ 02 апреля 2010

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

'(.?)\[(\w+)\b((?:[^"\'\[\]]++|(?:"[^"]*+")|(?:\'[^\']*+\'))*+)\](?:(?<=(\/)\])|([^\[\]]*+)\[\/\2\])(.?)'

Или, в более читабельном виде:

/(.?)              # could be [
 \[(\w+)\b         # tag name
 ((?:[^"'\[\]]++   # attributes
    |(?:"[^"]*+")
    |(?:'[^']*+')
  )*+
 )\]
 (?:(?<=(\/)\])   # '/' if self-closing
   |([^\[\]]*+)   # ...or content
    \[\/\2\]      # ...and closing tag
 )(.?)            # could be ]
/

Насколько я понимаю, $tagregexp в оригинале - это чередование всех названий тегов, которые были определены; Я заменил \w+ на удобочитаемость. Все, что записывает оригинальное регулярное выражение, тоже делает и в тех же группах. Единственное отличие состоит в том, что / в самозакрывающемся теге фиксируется в группе № 3 вместе с атрибутами, а также в ее собственной группе (# 4).

Я не думаю, что нужно изменить другое регулярное выражение, если вы не хотите добавить полную поддержку тегов, встроенных в значения атрибутов. Это также означало бы возможность использования кавычек в этом, и я не знаю, как вы захотите это сделать. Удвоение их было бы моим предположением; Вот как это делает Textpattern, и WordPress предположительно основан на этом.

Этот вопрос является хорошим примером того, почему такие приложения, как WordPress, не следует реализовывать с помощью регулярных выражений. Единственный способ добавить или изменить функциональность состоит в том, чтобы сделать регулярные выражения больше, уродливее и еще труднее поддерживать.

0 голосов
/ 02 апреля 2010

Какова ваша цель?Даже если бы регулярное выражение WordPress было лучше, шорткод не был бы выполнен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...