2

我正在寻找 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"]]

value 和 '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);

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

4

1 回答 1

1

我写了一个正则表达式,它匹配你所要求的一切,但会带来一些开销,我将在最后解释。但首先是正则表达式:

看起来像这样:

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

我会停下来让你理解它:

  • \[\[ ... \]\]比赛[[ ... ]],开始和结束
  • \s匹配任何空格(空格和制表符),\s+至少需要一个
  • (src|desc)匹配 stringsrc或 string desc这是一个 OR 运算符:匹配srcOR desc
  • '[^']*' 匹配两个单引号,以及介于两者之间的不是单引号的任何内容
  • "[^"]*"与双引号相同
  • ('[^']*'|"[^"]*")匹配以上两个之一
  • (src|desc)\s*=\s*('[^']*'|"[^"]*")匹配一个像src='something'
  • {1,2}匹配一次或两次,附加到上面的表达式,匹配其中一个或两个标记

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

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

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

你可以在这里在线测试

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

[[a ( (src|desc)=('[^']*'|"[^"]*") ){1,2} ]]
于 2013-01-24T06:34:01.920 回答