本文共 1300 字,大约阅读时间需要 4 分钟。
看一下内部引擎如何工作
知道正则表达式引擎如果工作可以让你很容易的构造出更好的正则表达式。这会帮助你理解为什么有的正则表达式并不如你预期的那样工作,这会帮你省下很多时间。
有2种正则表达式引擎,文本导向引擎和正则导向引擎。Jeffrey Friedl将他们称作DFA和NFA引擎(确定的有穷自动机和不确定的有穷自动机)。本文中谈到的正则引擎都是正则导向引擎。这是由于很多有用的特征,比如惰性和反向引用只能在正在导向引擎中实现,因此这种引擎的流行也不足为怪。
比较著名的使用文本导向引擎的工具有awk, egrep, flex, lex, MySQL和Procmail,awk和egrep,也有些版本使用的是正在导向引擎。
你可以很容易的知道所使用的正则表达式采用的是文本导向引擎还是正则导向引擎。如果可以使用反向引用或者惰性特性可以使用,那么可以确定采用的是正则导向引擎。你可以通过正则表达式regex|regex not测试字符串regex not来判断,如果匹配的是regex那么是正则导向的,如果匹配的是regex not,那么是文本导向的,这是因为正则引擎是“急切的”。
本文中在介绍一些新的正则符号后,将会逐步的解释正则引擎如何处理这些符号。某些时刻,探讨内部原理可能是比较啰嗦,但是理解正则引擎的工作原理会是非常有用的。
正则导向引擎:返回最左的匹配项
这个是重点,正则导向引擎总是返回最左的匹配项,即使在之后能发现一个更好的匹配项。当对一个字符串使用正则匹配的时候,引擎从字符串的第一个字符开始。它从第一个字符就尝试正则表达式所有的可能的排列。只有当所有的可能性都尝试了并且都失败了,正则引擎才继续匹配文本中的第二个字符。同样的,它尝试正则表达式所有可能的排列,以同样的命令。结果就是正则表达式返回了最左匹配项。
当用cat匹配He captured a catfish for his cat.,先试着拿正则表达式中的第一个字符c去匹配H。失败。此时正则表达式没有别的组合,因为它就包含了一组文本字符。所有正在引擎试着用c去匹配e,也失败了,就和c去匹配空格一样。到第4个字符的匹配。c匹配到了c,这是引擎继续试着用第2个符号a去匹配第5个字符,也成功。但是,接下来的t失败了。就在此时,引擎知道正则表达式从第4个字符开始不匹配,所一它继续从第5个字符a开始匹配。c匹配依旧失败,引擎继续前进。在第15个字符匹配了。c再次匹配了c。引擎继续试着匹配正则表达式中的剩余字符,并且发现a匹配a,t匹配t。
整个正则表达式可以从第15个字符处匹配。这个引擎非常“渴求的”输出这个匹配。因此,它会输出catfish中的前3个字母作为有效的匹配。引擎不会从继续下去了,不再尝试是否有更好的匹配,首个匹配它认为是足够好了。
第一个例子中,正则表达式引擎看上去似乎和正则文本查询程序类似。文本导向引擎也能返回相同的结果。但是在你的脑海中能有引擎执行的步骤也是非常重要,第二个例子中,引擎工作的方式对匹配有着深远的影响。某些结果可能会让人奇怪。但是一旦你知道引擎怎么工作,它总是按照逻辑并且是注定的。
转载地址:http://ihajx.baihongyu.com/