-2 本文用到的相关工具的版本
- Chrome=122.0.6261.69
- Nodejs=v10.19.0
- PHP 7.4.3-4ubuntu2.20 (cli) (built: Feb 21 2024 13:54:34) ( NTS )
- Python 3.8.10
- go version go1.13.8 linux/amd64
(不要吐槽和讨论版本,除非你确定这玩意在新版本上没问题,生产环境随便找台机器测的)
-1 这玩意哪来的?
这玩意是我们前端同学问 GPT ,如何写一个匹配网址的正则问到的。
(/^( https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/).test('https://foo.com/a-long-url-contains-path-and-query-and-anchor/foo/bar/baz?boo=baa#anchor'); *** (这个真的可以执行,建议新窗口 F12 试下) ***
于是,真的匹配一段文本的时候,就导致浏览器卡死了,无法做后续渲染,在 profiling 的时候查到是这个正则的问题。
0 MVP 测一下
function testRegexPerformance(repeatCount) { var testString = 'a'.repeat(repeatCount) + '#'; var regex = /(\w*)*$/; var startTime = process.hrtime(); var result = regex.test(testString); var endTime = process.hrtime(startTime); var executiOnTime= endTime[0] * 1000 + endTime[1] / 1000000; console.log("Repeat Count:", repeatCount); console.log("Execution Time:", executionTime + " milliseconds"); console.log("-----------------------------------" + result); } // 测试从 1 到 50 的重复次数 for (var i = 1; i <= 50; i++) { testRegexPerformance(i); } Repeat Count: 20 Execution Time: 35.191223 milliseconds -----------------------------------true Repeat Count: 21 Execution Time: 71.355698 milliseconds -----------------------------------true Repeat Count: 22 Execution Time: 140.852157 milliseconds -----------------------------------true Repeat Count: 23 Execution Time: 287.687666 milliseconds -----------------------------------true Repeat Count: 24 Execution Time: 577.368917 milliseconds -----------------------------------true Repeat Count: 25 Execution Time: 1148.243059 milliseconds -----------------------------------true Repeat Count: 26 Execution Time: 2297.804939 milliseconds 在i=25的时候,执行时间就到了秒级,之后都是指数级增长。
1 结果是 true 是符合预期的
*表示 0 个或者多个,没有任何一个\w 也是没问题的
2 Regexp.test vs String.match
# 不匹配 > 'a'.match(/(b)/) null # 匹配 > 'a'.match(/(b)/) null # 匹配 > 'aa'.match(/(a)/) [ 'a', 'a', index: 0, input: 'aa', groups: undefined ] # 不那么匹配 > 'aaa#'.match(/(\w*)*$/) [ '', undefined, index: 4, input: 'aaa#', groups: undefined ] # 匹配? > /(\w*)*$/.test('aaa#') true > 起因是我旁边的同学说.net 没有 test ,只有 match ,而且结果是 false
所以,js 里面如果用 match 试下,大概有三种结果:
- 匹配:test=true
- 不匹配:test=false
- 不太匹配:test=true ,但是 match[0]是空,1 是
undefined
3 其他语言的表现?
-
js:匹配,衰减
-
PHP: 不匹配,不衰减
-
Python:None(不匹配),衰减
-
Go: 匹配,不衰减
-
F#: 匹配,衰减
4 所以是为啥?
二楼放测试程序,不占地儿了
