标签之间的正则表达式,除非转义

时间:2013-02-18 20:29:09

标签: php regex

我围绕Pygments库制作了一个PHP包装器,突出了代码块。用于代码块检测的正则表达式可以在配置文件中配置。 (json格式)

在json值中看起来像这样:

{ 
    "codeblock_regex": "\\[pygments=(.*?)\\](.*?)\\[\\/pygments\\]" 
}

在JSON解码之后,它应该是这样的:

\[pygments=(.*?)\](.*?)\[\/pygments\]

这很糟糕,因为它不允许转义,我希望人们能够做到这一点:

\[pygments=lexer]some code here[/pygments]

用于检测\的pygments并忽略该代码块。我试过

 "(^\\\\)\\[pygments=(.*?)\\](.*?)\\[\\/pygments\\]"

json_decode之后应该是这样的:

 (^\\)\[pygments=(.*?)\](.*?)\[\/pygments\]

然而,这只是让它忽略了一切,甚至是普通的块,所以必定有一些我做错了。你可以看到,我远不是正则表达专家。

1 个答案:

答案 0 :(得分:1)

您需要的是一个相当棘手的正则表达式功能,称为"zero-width negative look-behind assertion"。 “零宽度”意味着它匹配输入的零个字符,“否定”意味着它只有在找到时才成功,而“look-behind”意味着它向后看。

这个的语法是(?<!test),其中test就是你不想去的地方。

在您的情况下,您希望匹配[,但如果前面有\,则忽略它,这两个都需要转义,因此您需要(?<!\\)\[

所以你的正则表达式最终为(在PHP中)$re = '/(?<!\\\\)\[pygments=(.*?)\](.*?)\[\/pygments\]/';

根据json_encode,然后在JSON中以"\/(?<!\\\\)\\[pygments=(.*?)\\](.*?)\\[\\\/pygments\\]\/"结尾。我认为我的眼睛开始变得有趣了所有的反斜杠... ;)