这个问题与PCRE有关。
我已经看到了对这个结构使用的嵌套括号的递归搜索:
\(((?>[^()]+)|(?R))*\)
问题在于,虽然' [^()] + '可以匹配包含换行符在内的任何字符,但您必须仅匹配单字符字符,例如大括号,括号,标点符号,单个字母等
我要做的是用任何一种模式替换'('和')'字符(例如'BEGIN'和'END'等关键字)。
我想出了以下结构:
(?xs) (?# <-- 'xs' ignore whitespace in the search term, and allows '.'
to match newline )
(?P<pattern1>BEGIN)
(
(?> (?# <-- "once only" search )
(
(?! (?P=pattern1) | (?P<pattern2>END)).
)+
)
| (?R)
)*
END
这实际上适用于看起来像这样的东西:
BEGIN <<date>>
<<something>
BEGIN
<<something>>
END <<comment>>
BEGIN <<time>>
<<more somethings>>
BEGIN(cause we can)END
BEGINEND
END
<<something else>>
END
这成功匹配任何嵌套的BEGIN..END对。
我分别为 BEGIN 和 END 设置了命名模式 pattern1 和 pattern2 。在搜索字词中使用 pattern1 可以正常工作。但是,我不能在搜索结束时使用 pattern2 :我必须写出'结束'。
我知道如何重写这个正则表达式,所以我只需要一次指定模式并在代码中“无处不在”使用它们吗?换句话说,所以我不必在搜索中间和最后都写 END 。
答案 0 :(得分:3)
要进一步扩展@Kobis的答案,请参阅以下正则表达式:
(?xs)
(?(DEFINE)
(?<pattern1>BEGIN)
(?<pattern2>END)
)
(?=((?&pattern1)
(?:
(?> (?# <-- "once only" search )
(?:
(?! (?&pattern1) | (?&pattern2)) .
)+
)*
| (?3)
)*
(?&pattern2)
))
这个正则表达式允许您甚至为每个单独的数据块获取数据!使用第3个反向引用,因为前两个已在定义块中定义。
答案 1 :(得分:0)
这看起来像(?(DEFINE))
块的一个很好的用例,用于创建这样的结构。 Perl的例子是:
(?xs)
(?(DEFINE)
(?<pattern1>BEGIN)
(?<pattern2>END)
)
(?&pattern1)
(
(?> (?# <-- "once only" search )
(
(?! (?&pattern1) | (?&pattern2)).
)+
)
| (?R)
)*
(?&pattern2)
(请注意我真的不知道任何perl,并且无法让它在任何在线测试人员上使用PHP)
另请参阅:http://www.pcre.org/pcre.txt(查找(?(DEFINE)
0看起来看起来没有页面)
适用于大多数口味的低技术解决方案是在模式的开头使用前瞻:
(?=.*?(?P<pattern1>BEGIN))
(?=.*?(?P<pattern2>END))
...
(?P=pattern1) (?# should work - it was captured )