状态,控制权交给“\1”。由于前面捕获组1捕获到的内容是“8”,所以“\1”要匹配到“8”才能匹配成功,而此时位置1后面的字符是“7”,匹配失败,“\d*?”回溯,尝试匹配位置1后面的字符“7”,再将控制权交给“\1”, 由“\1”匹配最后的“8”成功,此时整个表达式匹配成功。由于“(?<=(\d))”只匹配位置,不占有字符,所以整个表达式匹配到的结果为“78”,其中“\d*?”匹配到的是“7”,“\1”匹配到的是最后的“8”。
这与2.1.1节组合的匹配过程基本一致,只不过就是“\d*”和“\d*?”匹配与回溯过程有所区别而已。
2.1.4 源字符串二 + 正则表达式四匹配过程
源字符串二:9878
正则表达式四:(?<=(\d))\d*?\1
这一组合的匹配过程,与2.1.3节的匹配过程基本类似,这里不再赘述。
2.2 非贪婪模式子表达式匹配过程分析
2.2.1 源字符串一 + 正则表达式二匹配过程
源字符串一:878
正则表达式二:(?<=(\d)\d*?)\1
首先在位置0处开始尝试匹配,由“(?<=(\d)\d*?)”取得控制权,长度不固定,至少一位,由位置0处向左查找一位,失败,“(?<=(\d)\d*?)”匹配失败,导致第一轮匹配尝试失败。
正则引擎传动装置向前传动,由位置1处尝试匹配,控制权交给“(?<=(\d)\d*?)”,向左查找一位,接着将控制权交给“(\d)”,更进一步的将控制权交给“\d”。“\d”取得控制权后,向右尝试匹配,匹配“8”成功,将控制权交给“\d*?”,由于“\d*?”为非贪婪模式,会优先尝试忽略匹配,即不匹配任何内容,并记录回溯状态,此时“(\d)\d*?”匹配成功,那么“(?<=(\d)\d*?)”也就匹配成功,匹配结果为位置1,由于此处的子表达式“(\d)\d*?”为非贪婪模式,取得一个成功匹配项后,即交出控制权,同时丢弃所有回溯状态。由于前面捕获组1捕获到的内容是“8”,所以“\1”要匹配到“8”才能匹配成功,而此时位置1后面的字符是“7”,此时已无可供回溯的状态,整个表达式在位置1处匹配失败。
正则引擎传动装置向前传动,由位置2处尝试匹配,控制权交给“(?<=(\d)\d*?)”,向左查找一位,接着将控制权交给“(\d)”,更进一步的将控制权交给“\d”。“\d”取得控制权后,向右尝试匹配,匹配“7”成功,将控制权交给“\d*?”,由于“\d*?”为非贪婪模式,会优先尝试忽略匹配,即不匹配任何内容,并记录回溯状态,此时“(\d)\d*?”匹配成功,那么“(?<=(\d)\d*?)”也就匹配成功,匹配结果为位置2,由于此处的子表达式“(\d)\d*?”为非贪婪模式,取得一个成功匹配项后,即交出控制权,同时丢弃所有回溯状态。由于前面捕获组1捕获到的内容是“7”,所以“\1”要匹配到“7”才能匹配成功,而此时位置2后面的字符是“7”,此时已无可供回溯的状态,整个表达式在位置2处匹配失败。
位置3处的匹配过程也同样道理,最后“\1”因无字符可匹配,导致整个表达式匹配失败。
此时已尝试了字符串所有位置,均匹配失败,所以整个表达式匹配失败,未取得任何有效匹配结果。
2.2.2 源字符串二 + 正则表达式二匹配过程
源字符串一:9878
正则表达式二:(?<=(\d)\d*?)\1
这一组合的匹配过程,与2.2.1节的匹配过程基本类似,这里不再赘述。
2.3 贪婪模式子表达式匹配过程分析
2.3.1 源字符串一 + 正则表达式一匹配过程
源字符串一:878
正则表达式二:(?<=(\d)\d*)\1
首先在位置0处开始尝试匹配,由“(?<=(\d)\d*)”取得控制权,长度不固定,至少一位,由位置0处向左查找一位,失败,“(?<=(\d)\d*)”匹配失败,导致第一轮匹配尝试失败。
正则引擎传动装置向前传动,由位置1处尝试匹配,控制权交给“(?<=(\d)\d*)”,向左查找一位,接着将控制权交给“(\d)”,更进一步的将控制权交给“\d”。“\d”取得控制权后,向右尝试匹配,匹配