google DiffMatchPatch的正则表达式是否形式为(A * | B * | C * | D *)*?
private static final String TAG_REGEX = "<(\"[^\"]*\"|'[^']*'|[^'\">])*>"; //in case the texts being compared contain XML or HTML tags
如果我理解正确,某些输入字符串应该导致堆栈溢出,如http://www.regular-expressions.info/catastrophic.html,Regex gone wild: java.util.regex.Pattern matcher goes into high CPU loop所述?
有人可以举例说明会破坏这个正则表达式吗?
答案 0 :(得分:1)
正则表达式不会遇到灾难性的回溯,因为正则表达式是非模糊的。
但是,如果您使用的是Oracle JVM或OpenJDK,那么当单引号或双引号字符串之外存在大量字符时,上面的代码将受StackOverflowError
约束,尤其是带有不带引号的属性的HTML。
例如:
String input = "<a href=https://www.google.com/search?tbs=sbi:AMhZZisZE7GxcvzYV20Dr9-lbMIKPcIj1un1cusubzWm8vKUA4pt3wWZ_1T8F5DynP15tfGTUTz5nqFoQWqWtde44qYBjMwpISXp2yCcuxHNiOBQX96Ol_1Ipf1w-BNNwEteGZUxl6HX4niNUAvVJzMqyfs3p0CVyF9Vf5_1NnYssdzVEsCBpJDYE-g759Icjtlm8vZXWvq3RUGTLS7FOrkyTWQ1Ym9COR1jtJzAbLMhJT_1bMHM5i6SfUpspG7nW_10-XiHnNlW_10D7ApaO10mLaAFdRPm1qVjLBP0-R9Fz0wgeyEad28JXxKY8xBuAoOM5oW5SwLibZYFdMv_1OwgsHSjXZI6xcW7O7vgpcDUA-r5PjCFOm4mxBie2I0QylHAE4fqWELskrpg6MRCBo4lcS9mAceC4PPGWnBQi95s4Bg2qidUHOZ6FzXoGTFPSBJ6C65vVpijAS48qwUdT0LnyGyR4HgVoyXztnSVd18yHsNOMyhYp7SO3-jYYSZFOEoE8cVtEbBUlPEBLr6VsKEBf8pqCGHUS4T7dy5tlOIMXdT93r4MjilMOLhQq286l8oZhp9rNC1AxKuHvxQE4sh5kTzEs41LhF0sMm2PYPRB-vxTTD3RnPt47AZAkTsVJQAtgv-3_1optn69_1IDz0GHn0dRGR3Sd5Ekcx4SHb5XHGFBDJ-ejoCZ3IWzSo_1KMadJrWNOGojHkeX0lVkVeCa1N_111oUWxCqJ8ejUZfwMi1t7AgU7gdMmPC58oUlnNhwYqWxkOFN6YujVlFA7jDerSSIRL-TKdIrlc1egyiMYVZ-vSvpmKF2N7Qm4hcUEdwr9VD87Q27R2EfhsczHflOBZ7ensbnVYTzy6TgVJu8Wd5BortukJ860HfyexenbUNM9PtdwEDzfiNblJmUcahpgOPvfQlZjPZniLoGRO2KhMCrglu3yKD8ndRZu_1_1u_1ID_1xtsoJwCziNPTvaE5n2-bypPlY_1hFcMHB8d0dlOqF2D-YJoZu2qmNZzKYm0XkAgdX9rUEo6JtJdytvS5b46JQGvfGcvKFfWxeqbxc3rvE3uUcW1yK-4l5iz8dzQ42PoWxENXV5J0lAP2apcTgS068tKxaw8OSw5W1AWMLNY0WSeI7YeLD59xUlMXAyBSR25FtQBmV86taHP_1IxeNTwNF8pz20LLxmDT6CsG9LoXEEHGUPzr5rM2DMcgUw3_16_1Rp0zw_1h_1Ju-lgJ5bMP2KDxrSEKZ7neLdqPAfejMiAUV3_1miOk_1cOs8Gu0QKizmWt9yX7_14O9yrE1YQ6193rVnUqv7HIZ--WNzOxiVKOYaE_1Hy4gseyS0vh32oGlQBJslmk_1jXCi346Ffa-F2_1e6zfyjo-rMYw3d_14SYFZqXZL8dtIXJNQliBtsfn7dCInzkegkrhYRFcyLhppMWmZDurwMNhKQYbEZLC9lh8OabruxSTH1gkaDi0LlW0SpzJsXSwXSwgaRzFVTVNk2op4vPtVFs7NwD_187w2fDNJcIkkaIQ3cXQeQtzmhdvhLqhrudx9D7nAwdNwFM0gD2PVV2kUmc6YTJ6_1UQo2jS4ENycmXgg&btnG=Search%20by%20image&hl=en>";
问题的原因在this answer of mine分析。
解决此问题的一种方法是使外部重复具有占有性:
"<(\"[^\"]*\"|'[^']*'|[^'\">])*+>"
^^
占有量词用循环实现,因此不会有StackOverflowError
。
解决此问题的另一种方法是在外部重复的单次迭代中尽可能多地匹配不带引号的字符[^'\">]
:
"<(\"[^\"]*\"|'[^']*'|[^'\">]++)*>"
^^
在这种情况下,占有量词是强制,因为正则表达式会产生灾难性的回溯。