如何在PHP中匹配此模式

时间:2013-01-24 06:00:33

标签: php preg-replace

我在php中寻找一个正则表达式来解析以下模式的字符串。该命令由双方括号括起来

[[a src="" desc=""]]

其中a,src和desc是关键字(不会更改)。必须给出src但是desc是可选的,src或desc的值可以用双引号或单引号括起来。 src和desc可以按任何顺序给出。例如,以下模式都是有效的

[[a src="http://a.c.d" desc ="hello"]]
[[a src   ="http://a.c.d" desc= 'hello']]
[[a desc ="hello " src=  'http://a.c.d' ]]
[[a src = "http://a.c.d" ]]
[[a    src="http://a.c.d" desc ="hello"]]

值与'a','src','desc','='(不带引号)之间的任何空格都应该被忽略。我将用html标签替换此命令,如

SOMETHING_EXTRACT_FROM_DESC

考虑一个正则表达式来完成这项工作似乎很难。现在我有3个正则表达式设置来分别处理差异情况。看起来像这样

$pattern = '/\[\[a[:blank:]+src[:blank:]*=[:blank:]*"(.*?)"[:blank:]+desc[:blank:]*=[:blank:]+"(.*?)"\]\]/i';
$rtn = preg_replace($pattern, '<a href="${1}">${2}</a>', $src);

$pattern = '/\[\[a[:blank:]+desc[:blank:]*=[:blank:]*"(.*?)"[:blank:]+src[:blank:]*=[:blank:]+"(.*?)"\]\]/i';
$rtn = preg_replace($pattern, '<a href="${1}">${2}</a>', $rtn);

$pattern = '/\[\[a[:blank:]+src[:blank:]*=[:blank:]+"(.*?)"\]\]/i';
$rtn = preg_replace($pattern, '<a href="${1}">${2}</a>', $rtn);

但这不起作用,正则表达很难学习:(

1 个答案:

答案 0 :(得分:1)

我编写了一个匹配您请求的所有内容的正则表达式,但允许在最后解释一些开销。但首先是正则表达式:

看起来像这样:

\[\[a(\s+(src|desc)\s*=\s*('[^']*'|"[^"]*")){1,2}\s*\]\]

我会把它制成它以便你理解它:

  • \[\[ ... \]\]匹配[[ ... ]],开头和结尾
  • \s匹配任何空格(空格和标签),\s+至少需要一个
  • (src|desc)匹配字符串src或字符串desc这是一个OR运算符:匹配srcdesc
  • '[^']*'匹配两个单引号,介于两者之间的任何内容都不是单引号
  • "[^"]*"与双引号相同
  • ('[^']*'|"[^"]*")与上述两个
  • 中的一个匹配
  • (src|desc)\s*=\s*('[^']*'|"[^"]*")匹配src='something'
  • 等令牌
  • {1,2}匹配一两次内容,附加到上面的表达式,会遇到其中一个或两个令牌

这就是它。唯一的问题是它也会匹配这个:

[[a src="http://a.c.d" src="http://a.c.d"]]

我认为这是不匹配的。如果它不打扰你,那么你很高兴,否则你需要改变使用ors大原子的整个概念(即:|)并采取不同的方法。例如,您可以使用预测。但它会很快变得非常讨厌。

您可以在线测试 HERE

如果我删除反斜杠和\ s的东西,正则表达式更具可读性。这不起作用,但我认为它会帮助你理解它:

[[a ( (src|desc)=('[^']*'|"[^"]*") ){1,2} ]]