那么什么是回溯?
引擎采用默认贪婪的量词。贪婪修饰符匹配所有可能的和按需回溯,从而实现高效匹配,
由Greedy vs. Reluctant vs. Possessive Quantifiers引用:
greedy 量词首先尽可能匹配。所以.* 匹配整个字符串。然后匹配器尝试匹配下面的f,但没有剩余字符。所以它“回溯”,使贪婪的量词匹配更少的东西(使字符串末尾的“o”不匹配)。这仍然与正则表达式中的f 不匹配,因此它“回溯”了一步,使贪婪的量词再次匹配更少的东西(使字符串末尾的“oo”不匹配)。 still 与正则表达式中的f 不匹配,因此它又回溯了一步(使字符串末尾的“foo”不匹配)。现在,匹配器最终匹配了正则表达式中的f,并且o 和下一个o 也匹配了。成功! [...]
这和a*+b有什么关系?
在/a*+b/:
-
a 文字字符“a”。
-
*+ 零个或多个,占有。
-
b 文字字符"b"。
如Greedy vs. Reluctant vs. Possessive Quantifiers所引用:
占有量词就像贪婪量词一样,但它不会回溯。所以它以.* 匹配整个字符串开始,没有任何不匹配的内容。然后没有任何东西可以与正则表达式中的f 匹配。由于所有格量词不回溯,因此匹配失败。
为什么重要?
机器不会意识到它自己是否在进行(低效)匹配。请参阅此处以获取一个不错的示例:Program run forever when matching regex。在许多情况下,快速编写的正则表达式可能不是高效,而且很容易在部署中出现问题。
那么什么是原子团?
原子组内的模式完成匹配后,永远不会放手。研究这个例子:
Pattern: (?>\d\w{2}|12)c
Matching string: 12c
看起来完全合法,但是这个匹配失败。步骤很简单:原子组的第一个交替完美匹配 - \d\w{2} 消耗 12c。然后该组完成匹配 - 现在这里是我们的指针位置:
Pattern: (?>\d\w{2}|12)c
^
Matching string: 12c
^
模式前进。现在我们尝试匹配c,但没有c。匹配失败,而不是尝试回溯(释放\d\w{2} 并消耗12)。
那么这是个坏主意! Unihedron,我们为什么要防止回溯?
现在假设我们正在使用 JSON 对象进行操作。这个文件不小。从头开始回溯将是一个坏主意。
"2597401":[{"jobID":"2597401",
"account":"TG-CCR120014",
"user":"charngda",
"pkgT":{"pgi/7.2- 5":{"libA":["libpgc.so"],
"flavor":["default"]}},
"startEpoch":"1338497979",
"runTime":"1022",
"execType":"user:binary",
"exec":"ft.D.64",
"numNodes":"4",
"sha1":"5a79879235aa31b6a46e73b43879428e2a175db5",
"execEpoch":1336766742,
"execModify":"Fri May 11 15:05:42 2012",
"startTime":"Thu May 31 15:59:39 2012",
"numCores":"64",
"sizeT":{"bss":"1881400168","text":"239574","data":"22504"}},
{"jobID":"2597401",
"account":"TG-CCR120014",
"user":"charngda",
"pkgT":{"pgi/7.2-5":{"libA":["libpgc.so"],
"flavor":["default"]}},
"startEpoch":"1338497946",
"runTime":"33" "execType":"user:binary",
"exec":"cg.C.64",
"numNodes":"4",
"sha1":"caf415e011e28b7e4e5b050fb61cbf71a62a9789",
"execEpoch":1336766735,
"execModify":"Fri May 11 15:05:35 2012",
"startTime":"Thu May 31 15:59:06 2012",
"numCores":"64",
"sizeT":{"bss":"29630984","text":"225749","data":"20360"}},
{"jobID":"2597401",
"account":"TG-CCR120014",
"user":"charngda",
"pkgT":{"pgi/7.2-5": {"libA":["libpgc.so"],
"flavor":["default"]}},
"startEpoch":"1338500447",
"runTime":"145",
"execType":"user:binary",
"exec":"mg.D.64",
"numNodes":"4",
"sha1":"173de32e1514ad097b1c051ec49c4eb240f2001f",
"execEpoch":1336766756,
"execModify":"Fri May 11 15:05:56 2012",
"startTime":"Thu May 31 16:40:47 2012",
"numCores":"64",
"sizeT":{"bss":"456954120","text":"426186","data":"22184"}},{"jobID":"2597401",
"account":"TG-CCR120014",
"user":"charngda",
"pkgT":{"pgi/7.2-5":{"libA":["libpgc.so"],
"flavor":["default"]}},
"startEpoch":"1338499002",
"runTime":"1444",
"execType":"user:binary",
"exec":"lu.D.64",
"numNodes":"4",
"sha1":"c6dc16d25c2f23d2a3321d4feed16ab7e10c2cc1",
"execEpoch":1336766748,
"execModify":"Fri May 11 15:05:48 2012",
"startTime":"Thu May 31 16:16:42 2012",
"numCores":"64",
"sizeT":{"bss":"199850984","text":"474218","data":"27064"}}],
哦哦...
你现在明白我的意思了吗? :P
剩下的让你自己去弄清楚,并尝试更多地了解所有格量词和原子团;我不会在这篇文章中写任何其他内容。这里是json的出处,前几天看到了答案,很受启发:REGEX reformatting。
另请阅读