我围绕Pygments库制作了一个PHP包装器,突出了代码块。用于代码块检测的正则表达式可以在配置文件中配置。 (json格式)
在json值中看起来像这样:
{
"codeblock_regex": "\\[pygments=(.*?)\\](.*?)\\[\\/pygments\\]"
}
在JSON解码之后,它应该是这样的:
\[pygments=(.*?)\](.*?)\[\/pygments\]
这很糟糕,因为它不允许转义,我希望人们能够做到这一点:
\[pygments=lexer]some code here[/pygments]
用于检测\
的pygments并忽略该代码块。我试过
"(^\\\\)\\[pygments=(.*?)\\](.*?)\\[\\/pygments\\]"
在json_decode
之后应该是这样的:
(^\\)\[pygments=(.*?)\](.*?)\[\/pygments\]
然而,这只是让它忽略了一切,甚至是普通的块,所以必定有一些我做错了。你可以看到,我远不是正则表达专家。
答案 0 :(得分:1)
您需要的是一个相当棘手的正则表达式功能,称为"zero-width negative look-behind assertion"。 “零宽度”意味着它匹配输入的零个字符,“否定”意味着它只有在不找到时才成功,而“look-behind”意味着它向后看。
这个的语法是(?<!test)
,其中test
就是你不想去的地方。
在您的情况下,您希望匹配[
,但如果前面有\
,则忽略它,这两个都需要转义,因此您需要(?<!\\)\[
所以你的正则表达式最终为(在PHP中)$re = '/(?<!\\\\)\[pygments=(.*?)\](.*?)\[\/pygments\]/';
根据json_encode
,然后在JSON中以"\/(?<!\\\\)\\[pygments=(.*?)\\](.*?)\\[\\\/pygments\\]\/"
结尾。我认为我的眼睛开始变得有趣了所有的反斜杠... ;)