我遇到了一个正则表达式的问题,我写的是为了匹配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
)
如您所见,第二个匹配(应该是文本,因为第一个是可选的)包括开始标记的结尾和所有结束标记但最后一个括号。
编辑:发现返回的匹配是第一次捕获,而不是第二次捕获。 See the regex in Regexr.
请帮忙吗?我真的很沮丧。
答案 0 :(得分:8)
在你的正则表达式中:
\[$shortcode(.+?)?\](?:(.+?)?\[\/$shortcode\])?
第一个捕获组(.+?)
至少匹配1个字符。
整个群组都是可选的,但在这种情况下,它恰好匹配到最后]
的所有内容。
以下正则表达式有效:
\[$shortcode(.*?)?\](?:(.+?)?\[\/$shortcode\])?
*
量词表示0或更多,而+
表示一个或多个。
答案 1 :(得分:3)
当然这是来自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) )...