这个问题与PCRE有关。
我已经看到了与此结构一起使用的嵌套括号的递归搜索:
(((?>[^()]+)|(?R))*)
这样做的问题是,虽然">[^((]+"可以匹配包括换行符在内的任何字符,但您被迫只匹配单字符字符,例如大括号、括号、标点符号、单个字母等。
我正在尝试做的是用任何类型的模式替换"("和"("字符(例如"开始"和"结束"等关键字(。
我想出了以下结构:
(?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..结束对。
我分别为 BEGIN 和 END 设置了命名模式模式 1 和模式 2。在搜索词中使用模式 1 工作正常。但是,我不能在搜索结束时使用 pattern2:我必须写出">END"。
知道如何重写此正则表达式,以便我只需要指定一次模式并在代码中的"任何地方"使用它们吗?换句话说,所以我不必在搜索过程中和最后都写 END。
要进一步扩展@Kobis答案,请参阅以下正则表达式:
(?xs)
(?(DEFINE)
(?<pattern1>BEGIN)
(?<pattern2>END)
)
(?=((?&pattern1)
(?:
(?> (?# <-- "once only" search )
(?:
(?! (?&pattern1) | (?&pattern2)) .
)+
)*
| (?3)
)*
(?&pattern2)
))
这个正则表达式将允许您甚至获取每个单独数据块的数据!使用第三个反向引用,因为前两个已在定义块中定义。
演示:http://regex101.com/r/bX8mB6
看起来像是用于创建此类构造的(?(DEFINE))
块的一个很好的用例。一个Perl的例子是:
(?xs)
(?(DEFINE)
(?<pattern1>BEGIN)
(?<pattern2>END)
)
(?&pattern1)
(
(?> (?# <-- "once only" search )
(
(?! (?&pattern1) | (?&pattern2)).
)+
)
| (?R)
)*
(?&pattern2)
示例:http://ideone.com/8o9cg
(请注意,我真的不了解任何perl,也无法在任何在线测试人员的PHP上运行(
另请参阅:http://www.pcre.org/pcre.txt(查找(?(DEFINE)
0,看起来他们没有页面(
适用于大多数口味的低技术解决方案是在模式开始时使用前瞻:
(?=.*?(?P<pattern1>BEGIN))
(?=.*?(?P<pattern2>END))
...
(?P=pattern1) (?# should work - it was captured )