f <<FOO,10,<<BAR,20 some text FOO some more text BAR
我想在Perl的风格中使用backrefs和递归调用,但无法使cross-serial dependencies工作(即,无法反转捕获的backrefs,因为FOO应该在BAR之前匹配).我还想过在.Net上平衡组,我可以通过使用前瞻来反转堆栈(我知道,这是一个可怕的黑客),像这样:
(?:(?<x>foo|bar|baz)|\s)+(?(x)|(?!))\s*(?(x)(?=(.*?)(?<-x>(?<y>\k<x>)))){3}(?(x)(?!))(?:(?(y)(?<-y>\k<y>))|\s)+(?(x)(?!))(?(y)(?!))
(单击here进行测试.)
这匹配foo bar baz foo bar baz,但后来我必须添加一个手动计数器({3}),因为前瞻不会重复,因为它不消耗我假设的任何输入.因此,这对任意案件都不起作用(但它很接近!).当然,我可以用{1000}或任何其他大数字替换它,这将回答我的问题,但我想知道是否还有其他方法.
致谢:我确实理解将这种构造与正则表达式相匹配并不是一个好主意.我正在做这方面的研究工作,我想知道是否有可能.如果是,please do not use it in production code.
关键的一点是,在任何时候,正则表达式引擎只有2条信息.
这很容易忘记,因为与蒸汽解析不同,正则表达式引擎可以在匹配失败时回溯(这通常会做很多事情).而且cpu速度足够快,每秒可能会失败数百万次!虽然正则表达式似乎有更多的记忆,因为它可以匹配“第一只猫后狗”,它只知道它已经看到了单词dog,因为它目前正在寻找猫中的c.或者换句话说,当前状态是可能的,因为满足了特定的前提条件.
对于模式的有限数量的排列,足够长的正则表达式可以匹配任何东西. (正则表达式的长度可能是灵魂/ cpu破碎,但技术上可行)
模式不是有限的,比如“匹配一个a后跟相同数量的bs”(ex“ab”“aabb”“aaabbb”等)正则表达式没有机制记住它看到了多少a,所以它不知道要匹配多少b.您可以通过尝试匹配所有变体(ab | aabb | aaabbb | aaaabbbb | …)来解决这个问题,但是解析这将是非常昂贵的,并且您将无法捕获每个有效输入,因为我总是可以添加一个更多ab对.
所以,你需要问自己2个问题
>我想要匹配的有限数量的排列吗?
>我的灵魂/ cpu会存在这样的正则表达式吗?
相关的,您应该在Nondeterministic finite automaton阅读.由于您要求研究原因,并且任何纯正则表达式引擎都是NDFA,因此有必要知道它们受到相同的已知限制.
TL:DR;
使用纯正则表达式引擎……
实际上,是的,但是以牺牲灵魂为代价.从理论上说,不,根本不是.永远都会有一个有效的案例,你的正则表达式会失败.