如何在php中匹配此模式

如何在php中匹配此模式,php,preg-replace,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

我正在寻找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标记替换此命令,如

从描述中提取的东西

似乎很难想到一个正则表达式来完成这项工作。现在我有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);
$pattern='/\[\[a[:blank:][+src[:blank:][*=[:blank:][*](.*?”[:blank:][+desc[:blank:][*=[:blank:][+”(.*?“\]\]/i';
$rtn=preg_replace($pattern,,$src);
$pattern='/\[\[a[:blank:][+desc[:blank:][*=[:blank:][*](.*?“[:blank:][+src[:blank:][*=[:blank:][+”(.*?“\]\]/i';
$rtn=preg_replace($pattern,,$rtn);
$pattern='/\[\[a[:blank:][+src[:blank:][*=[:blank:][+”(.*?“\]\]]/i';
$rtn=preg_replace($pattern,,$rtn);

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

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

看起来像这样:

\[\[a(\s+(src|desc)\s*=\s*('[^']*'|"[^"]*")){1,2}\s*\]\]
我会把它刹住让你明白:

[[a ( (src|desc)=('[^']*'|"[^"]*") ){1,2} ]]
  • \[\[…\]\]
    匹配
    [[…]]
    ,开头和结尾
  • \s
    匹配任何空格(空格和制表符),
    \s+
    至少需要一个空格
  • (src | desc)
    匹配字符串
    src
    或字符串
    desc
    它是一个or运算符:匹配
    src
    desc
  • “[^']*
    ”匹配两个单引号以及介于两者之间的任何非单引号的内容
  • “[^”]*”
    与双引号相同
  • (“[^']*”|“[^”]*”
    匹配上述两个选项之一
  • (src | desc)\s*=\s*('[^']*'.[^']*“[^']*”)
    匹配类似于
    src='something'
  • {1,2}
    匹配某个事物一次或两次,在上述表达式的后面,匹配其中一个或两个标记
基本上就是这样。唯一的问题是它也会匹配这个:

[[a src="http://a.c.d" src="http://a.c.d"]]
我认为这是不匹配的。如果你不介意的话,你可以走,否则你需要改变使用ors的大原子的整个概念(即:
),并采取不同的方法。你可以使用look aheads,例如。但它会很快变得非常糟糕

您可以在线测试它

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

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

谢谢SinistraD。它看起来很整洁,但我还是不太明白。我只有一个问题。因为模式字符串中有“和”的混合。如何将其放入php字符串中以避免语法错误。我通过用“”或“”包装模式来尝试您的代码但两者都不行。使用简单的引号并在字符串中的每个引号前添加反斜杠:例如:
“字符串内的引号:\'continuenting string'
。使用的反斜杠不会成为字符串的一部分,它们会使单引号成为。非常感谢。这是一个很好的起点。我也喜欢你发布的测试网站,它是也帮助我学习regex:)不用客气,很高兴我能帮上忙。我总是使用这个工具来构建我的正则表达式。它真的很方便,这就是为什么我在我给出的每个正则表达式答案中都推荐它。