“8”成功,将控制权交给“\d*”,由于“\d*”为贪婪模式,会优先尝试匹配,并记录回溯状态,但此时已没有可用于匹配的字符,所以匹配失败,回溯,不匹配任何内容,丢弃回溯状态,此时“(\d)\d*”匹配成功,匹配内容为“8”,那么“(?<=(\d)\d*)”也就匹配成功,匹配结果是位置1,由于此处的子表达式为贪婪模式,“(\d)\d*”取得一个成功匹配项后,需要查找是否还有更长匹配,找到最长匹配后,才会交出控制权。再向左查找,已没有字符,“8”已是最长匹配,此时交出控制权,同时丢弃所有回溯状态。由于前面捕获组1捕获到的内容是“8”,所以“\1”要匹配到“8”才能匹配成功,而此时位置1后面的字符是“7”,此时已无可供回溯的状态,整个表达式在位置1处匹配失败。
正则引擎传动装置向前传动,由位置2处尝试匹配,控制权交给“(?<=(\d)\d*)”,向左查找一位,接着将控制权交给“(\d)”,更进一步的将控制权交给“\d”。“\d”取得控制权后,向右尝试匹配,匹配“7”成功,将控制权交给“\d*”,由于“\d*”为贪婪模式,会优先尝试匹配,并记录回溯状态,但此时已没有可用于匹配的字符,所以匹配失败,回溯,不匹配任何内容,丢弃回溯状态,此时“(\d)\d*”匹配成功,匹配内容为“7”,那么“(?<=(\d)\d*)”也就匹配成功,匹配结果是位置2,由于此处的子表达式为贪婪模式,“(\d)\d*”取得一个成功匹配项后,需要查找是否还有更长匹配,找到最长匹配后,才会交出控制权。再向左查找,由位置0处向右尝试匹配,“\d”取得控制权后,匹配位置0处的“8”成功,将控制权交给“\d*”,由于“\d*”为贪婪模式,会优先尝试匹配,并记录回溯状态,匹配位置1处的“7”成功,此时“(\d)\d*”匹配成功,那么“(\d)\d*”又找到了一个成功匹配项,匹配内容为“87”,其中捕获组1匹配到的是“8”。再向左查找,已没有字符,“87”已是最长匹配,此时交出控制权,同时丢弃所有回溯状态。由于前面捕获组1捕获到的内容是“8”,所以“\1”匹配位置2处的“8”匹配成功,此时整个有达式匹配成功。
演示例程中用的是Match,只取一次匹配项,事实上如果用的是Matches,正则表达式是需要尝试所有位置的,对于这一组合,同样道理,在位置3处,由于“\1”没有字符可供匹配,所以匹配一定是失败的。
至此,这一组合的匹配完成,有一个成功匹配项,匹配结果为“8”,匹配开始位置为位置2,也就是匹配到的内容为第二个“8”。
2.3.2 源字符串二 + 正则表达式一匹配过程
源字符串二:9878
正则表达式二:(?<=(\d)\d*)\1
首先在位置0处开始尝试匹配,由“(?<=(\d)\d*)”取得控制权,长度不固定,至少一位,由位置0处向左查找一位,失败,“(?<=(\d)\d*)”匹配失败,导致第一轮匹配尝试失败。
正则引擎传动装置向前传动,由位置1处尝试匹配,这一轮的匹配过程与2.3.1节的组合在位置1处的匹配过程类似,只不过“(\d)\d*”匹配到的是“9”,捕获组1匹配到的也是“9”,因此“\1”匹配失败,导致整个表达式在位置1处匹配失败。
正则引擎传动装置向前传动,由位置2处尝试匹配,这一轮的匹配过程与2.3.1节的组合在位置2处的匹配过程类似。首先“(\d)\d*”找到一个成功匹配项,匹配到的内容是“8”,捕捉组1匹配到的内容也是“8”,此时再向左尝试匹配,又找到一个成功匹配项,匹配到的内容是“98”,捕捉组1匹配到的内容也是“9”,再向左查找时,已无字符,所以“98”就是最长匹配项,“(?<=(\d)\d*)”匹配成功,匹配结果是位置2。由于此时捕获组1匹配的内容是“9”,所以“\1”在位置2处匹配失败,导致整个表达式在位置2处匹配失败。
正则引擎传动装置向前传动,由位置3处尝试匹配,这一轮的匹配过程与上一轮在位置2处的匹配过程类似。首先“