5

我为匹配 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
)

如您所见,第二个匹配项(应该是文本,因为第一个是可选的)包括开始标记的结尾和除最后一个括号之外的所有结束标记。

编辑:发现返回的匹配是第一个捕获,而不是第二个。请参阅 Regexr 中的正则表达式。

你能帮忙吗?我真的在这个问题上崩溃了。

4

2 回答 2

11

在您的正则表达式中:

\[$shortcode(.+?)?\](?:(.+?)?\[\/$shortcode\])?

第一个捕获组(.+?)至少匹配 1 个字符。

整个组是可选的,但在这种情况下,它恰好匹配到最后一个]

以下正则表达式有效:

\[$shortcode(.*?)?\](?:(.+?)?\[\/$shortcode\])?

*量词表示0或多个,而表示+一个或多个。

于 2012-07-05T14:32:30.730 回答
5

当然这是来自 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) )...
于 2014-10-15T13:34:27.770 回答