我读了 http://swtch.com/~rsc/regexp/regexp1.html,作者说,为了在正则表达式中有反向引用,匹配时需要回溯,这使得最坏情况的复杂度呈指数增长.但是我不明白为什么反向引用需要回溯.有人可以解释为什么,也许提供一个例子(正则表达式和输入)?
要直接了解您的问题,您应该对 Chomsky Hierarchy进行简短的研究.这是一种以越来越复杂的方式组织正式语言的古老而美丽的方式.层次结构的最低级别是常规语言.你可能会猜到 – 你是对的 – RL是那些可以用“纯粹”正则表达式表示的那些:只有字母表,空字符串,连接,交替|和Kleene star *(看Ma,没有反参考).形式语言理论的经典定理 – 克莱恩定理 – 是,DFA,(如你所引用的文章中描述的)和正则表达式都具有完全相同的权力来表示和识别语言.汤普森在文章中给出的建议是定理证明的一部分.

每个RL也是CFL.但是,无限次的CFL是不正常的. CFL中存在的一个功能,使它们太复杂,无法成为常规的平衡对象:括号,开始块等.几乎所有的编程语言都是CFL. CFL可以通过所谓的下推自动机被有效地识别,这本质上是一个粘贴了NPC的NFA.堆栈根据需要增长到很大,因此它不再是有限自动机.实际编程语言的解析器几乎都是下推自动机的变体.

考虑使用反引号的正则表达式

^(b*a)\1$

换句话说,这表示一些n的长度为2n的字符串,其中第n个和第2n个字符都是a,所有其他字符都是b.这是一个非常规的CFL的完美示例.你可以用另外一种很酷的形式语言工具来证明这一点,称之为抽象引理.

这正是为什么回参考引起问题!它们允许表示不常规语言的“正则表达式”.因此,没有NFA或DFA无法识别它们.

但是,等等,这甚至比我已经这么远了.考虑

^(b*a)\1\1$

我们现在有一个长度为3n的字符串,其中第n个,第2n个和第3个元素是a,所有其他元素都是b.还有另外一种抽搐法的风味,可以证明这种语言太复杂,不能成为CFL!没有下推自动机可以识别这个.

后面的引用允许这些增强的正则表达式表示Chomsky层次结构上的三个语言:语境敏感语言.大致来说,识别csl的唯一方法是检查所有长度相同的字符串(至少如果P!= NP,但是对于所有实际目的都是如此,并且完全不同).这些字符串的数量在您匹配的字符串的长度上是指数的.

这就是为什么需要搜索正则表达式匹配器的原因.你可以非常聪明的设计搜索的方式.但是,总是会有一些投入使它花费指数时间.

所以我同意你引用的论文的作者.可以编写完美无瑕的正则表达式,没有后退参考,几乎所有输入都将被高效地识别,但是存在导致Perl或Java或Python正则表达式匹配器的一些输入,因为它是一个回溯搜索 – 要求数百万几年完成比赛.这太疯狂了.你可以有一个脚本是正确的,工作正常多年,然后锁定一天只是因为它绊倒了一个坏的输入.假设正则表达式被掩埋在你正在骑的飞机上的导航系统的消息解析器中

编辑

根据要求,我将描述如何使用抽水引理来证明语言a ^ k b a ^ k b不是常规的.这里^ k是重复k次的缩写. PL表示必须存在正整数N,使得长度至少为N的常规语言中的每个字符串必须具有R S T的形式,使得R S ^ k T也在所有自然k的语言中.这里R,S,T是字符串,S可能不为空.

PL的证明取决于每个常规语言对应于一些DFA的事实.这个DFA的接受输入长于其状态数(相当于引文中的L)必须使其“循环:”重复一个状态.调用这个状态X.机器消耗一些字符串R从起始到X,然后S循环回X,然后T到达接受状态.那么,在输入中添加S的额外副本(或者删除S)只对应于从X返回到X的不同数量的“循环”.因此,还将接受带有附加(或删除的)S副本的新字符串.

由于每个RL都必须满足PL,所以证明语言不是常规的证明,表明它与PL相矛盾.对于我们的语言,这并不难.假设你试图说服我的语言L = a ^ k b a ^ k b满足PL.因为这样做,你必须能够给我一些N值(见上文):一个假设的DFA中识别L的状态数.在这一点上,我会说:“好吧,普通人先生,考虑字符串B = a ^ N ba ^ N b.“如果L是常规的,B必须使这个DFA(不管它是什么样的)在前N个字符中循环,这必须全部为!所以循环(上面的字符串S)也包括所有的.有了这个,我可以立即显示你对L的正常要求是假的.我只是选择第二次绕圈.这将导致您的这个假设的DFA接受一个新的字符串a ^ M b a ^ N b,其中M> N,因为我添加了上半部分.哎哟!这个新的字符串不在L中,所以PL毕竟不是真的.由于我每次都可以做这个技巧,无论你提供什么,PL都不能持有L,而L不能一直是正常的.

由于它不是常规的,所以Kleene的定理告诉我们,没有描述它的DFA或FA和“纯粹”正则表达式.

背面参考的证明允许甚至没有上下文的语言具有非常相似的环,但需要下推自动机的背景,我不会在这里给出. Google将提供.

注意:这两个都没有证明后退参考使得NP完整.他们只是以非常严格的方式来说,反驳引用了纯正则表达式的真正复杂性.它们允许任何无限制存储器的机器无法识别的语言,也不允许只有无限大的LIFO存储器.我会把NP的完整性证明给别人.

正则表达式中的反向引用如何使回溯需要?的更多相关文章

  1. HTML5数字输入仅接受整数的实现代码

    这篇文章主要介绍了HTML5数字输入仅接受整数的实现代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  2. ios – 使用大写符号在字符串swift中获取URL的正则表达式

    我尝试在文本中获取URL.所以,在此之前,我使用了这样一个表达式:但是当用户输入带有大写符号的URL时(例如Http://Google.com,它与它不匹配)我遇到了问题.我试过了:但什么都没发生.解决方法您可以使用正则表达式中的i内联标志关闭区分大小写,有关可用正则表达式功能的详细信息,请参阅FoundationFrameworkReference.(?ismwx-ismwx)Flagsetti

  3. ios – 如何在Swift 3中使用正则表达式?

    解决方法我相信.当没有其他选项适用时,将使用.allZeros.因此,使用Swift3,您可以传递一个空的选项列表或省略options参数,因为它默认为无选项:要么请注意,在Swift3中,您不再使用error参数.它现在抛出.

  4. ios – lldb断点在类目标c中的所有方法

    如何使用lldb在ObjectiveC类中的所有方法上自动设置断点?

  5. swift的正则表达式(NSRegularExpression)

    init(_pattern:String){varerror:NSError?

  6. swift 正则表达式运用实例选自《swifter 100个swift开发必备tip 》

  7. swift算法实践4)-trie自动机

    1、trie自动机是识别字符串的确定性有向无环自动机2、图示3、构造代码F包括了状态q所对应的P中的字符串

  8. swift手记-trie自动机

    1、trie自动机是识别字符串的确定性有向无环自动机2、图示3、构造代码F包括了状态q所对应的P中的字符串

  9. Swift截取HTML中的所有图片url

    在Swift中,要从HTML格式的String中截取出所有的img的所有图片url,要截取的url就要匹配url,需要用到正则表达式。

  10. 收藏swift正则表达式的各种验证

    1.验证邮箱classfuncvalidateEmail(email:String)->Bool{varemailString="[A-Z0-9a-z._%-]@[A-Za-z0-9.-]\\.[A-Za-z]{2,4}"varemailPredicate=nspredicate(format:"SELFMATCHES%@",emailString)returnemailPredicate.eva

随机推荐

  1. 法国电话号码的正则表达式

    我正在尝试实施一个正则表达式,允许我检查一个号码是否是一个有效的法国电话号码.一定是这样的:要么:这是我实施的但是错了……

  2. 正则表达式 – perl分裂奇怪的行为

    PSperl是5.18.0问题是量词*允许零空间,你必须使用,这意味着1或更多.请注意,F和O之间的空间正好为零.

  3. 正则表达式 – 正则表达式大于和小于

    我想匹配以下任何一个字符:或=或=.这个似乎不起作用:[/]试试这个:它匹配可选地后跟=,或者只是=自身.

  4. 如何使用正则表达式用空格替换字符之间的短划线

    我想用正则表达式替换出现在带空格的字母之间的短划线.例如,用abcd替换ab-cd以下匹配字符–字符序列,但也替换字符[即ab-cd导致d,而不是abcd,因为我希望]我如何适应以上只能取代–部分?

  5. 正则表达式 – /bb | [^ b] {2} /它是如何工作的?

    有人可以解释一下吗?我在t-shirt上看到了这个:它似乎在说:“成为或不成为”怎么样?我好像没找到’e’?

  6. 正则表达式 – 在Scala中验证电子邮件一行

    在我的代码中添加简单的电子邮件验证,我创建了以下函数:这将传递像bob@testmymail.com这样的电子邮件和bobtestmymail.com之类的失败邮件,但是带有空格字符的邮件会漏掉,就像bob@testmymail也会返回true.我可能在这里很傻……当我测试你的正则表达式并且它正在捕捉简单的电子邮件时,我检查了你的代码并看到你正在使用findFirstIn.我相信这是你的问题.findFirstIn将跳转所有空格,直到它匹配字符串中任何位置的某个序列.我相信在你的情况下,最好使用unapp

  7. 正则表达式对小字符串的暴力

    在测试小字符串时,使用正则表达式会带来性能上的好处,还是会强制它们更快?不会通过检查给定字符串的字符是否在指定范围内比使用正则表达式更快来强制它们吗?

  8. 正则表达式 – 为什么`stoutest`不是有效的正则表达式?

    isthedelimiter,thenthematch-only-onceruleof?PATTERN?

  9. 正则表达式 – 替换..与.在R

    我怎样才能替换..我尝试过类似的东西:但它并不像我希望的那样有效.尝试添加fixed=T.

  10. 正则表达式 – 如何在字符串中的特定位置添加字符?

    我正在使用记事本,并希望使用正则表达式替换在字符串中的特定位置插入一个字符.例如,在每行的第6位插入一个逗号是什么意思?如果要在第六个字符后添加字符,请使用搜索和更换从技术上讲,这将用MatchGroup1替换每行的前6个字符,后跟逗号.

返回
顶部