正则表达式(二)--表达式匹配原理


规则1:优先选择最左端的匹配结果

这个规则 没有规定优先 匹配结果的长度,只是规定在所有可能匹配的结果中,优先选择最左端的。
匹配的过程:
    先从第一个位置测试 整个表达式 能匹配的每样文本,如果在当前位置找不到结果,就需要从字符串的第二个字符开始重新匹配,直到字符串最后一个字符都不能找到匹配结果的话,才会报告匹配失败。
例如:用'ORA' 匹配 FLORAL, 第一轮ORA 不能匹配FLO,第二轮ORA不能匹配LOR,从第三轮开始尝试能够成功,所以引擎会停下来。

例如:用'cat' 匹配 'The belly indicates that your cate is too' 文本,由于最左端匹配 ,结果是 indicates 而不是后边的cat.

例如:用'fat|cat|belly|your' 来匹配 'The dragging belly indicates...',结果是belly, 因为是第一个字符开始匹配的整个表达式 符合的文本。在移动之前,fat,cat,belly,your都必须尝试。

规则2:标准量词是匹配优先的。


在使用星号,加号,多选结构等功能更强大的元字符时,需要知道,标准量词(?,*,+)以及{min,max}都是‘匹配优先’的。
在匹配成功之前,进行尝试的次数是存在上限与下限的。他们总是尝试匹配尽可能多的字符,知道匹配上限为止。
例如:'[0-9]+'能匹配'March1998'中的所有数字,1匹配之后实际已经满足了成功的下限,但因为是匹配优先的,所以不会停在此处,继续匹配'998'直到字符串末尾。

过度的匹配优先
'^.*[0-9][0-9]$',匹配一行字符的最后两位数字。
匹配过程:'.*'首先会匹配整行,而[0-9][0-9]是必须匹配的,在尝试匹配行末的时候会失败,这时它会通知'.*',让'.*'交出一些字符来让它匹配。
匹配优先组件(标准量词) 首先会匹配尽可能多的字符,但为了整个表达式的匹配,他们通常需要"释放"一些字符。
'^.*([0-9][0-9])$' 匹配'aaaaa24bbbbbccc' 的过程: .*匹配整个字符串以后,第一个[0-9]匹配要求'.*'释放第一个字符'c'(最后的字符).这时[0-9]并不能匹配,所以'.*'一直释放字符,直到释放'4'为止。

注意:
用 '^.*([0-9])+$' 来匹配 'Copyright 2003.', 这里括号捕获到的是 末尾数字3。
在这个例子中,释放的字符是最后的'3',这里'必须'匹配的元素是[0-9],所以'.*'只会交出3,不会交出0,如果是[0-9][0-9],这里有两个必须匹配的元素,会交出0与3.

表达式引擎


NFA引擎:表达式主导


用'to(nite|knight|night)'匹配文本'..tonight..'
过程:第一个元素是t,它会重复尝试,直到在目标字符串中找到't'为止,之后就检查紧随其后的字符是否能由o匹配,如果能就检查下面的元素。
下面的元素是(nite|knight|night),引擎会分为三个分支,依次尝试这3种可能。
尝试匹配nite的过程与之前一样,先匹配n然后是i然后是t然后是e.如果失败,引擎会尝试另一种可能,表达式的控制权在不同元素之间切换,所以称它为'表达式主导';


DFA引擎:文本主导


还是上面的匹配例子
文本位置:after..toni^ght ^代表当前遍历文本的位置。
正则表达式位置: to(ni^te|knight|ni^ght).
有效的可能变成了两个。 不合适的匹配子表达式可能在后续文字时被去除。

比较:DFA引擎要比NFA 引擎要快些。
NFA 目标文本中某个字符可能会被正则表达式不同部分重复检测。即使某个表达式能够匹配,为了检查表达式剩下的部分,也可能需要再一次应用。
DFA 目标文本中的每个字符只会检查(最多)一遍。
NFA: 非确定型有穷自动机。
DFA: 确定型有穷自动机。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值