在 ECMAScript 2020 中,正则表达式(RegExp)的使用得到了一些改进和优化。本文将介绍这些新特性,并提供一些优化建议和示例代码。
新特性
1. s
修饰符
在以前的版本中,.
通常匹配除了换行符以外的任何字符。但是,如果我们想要匹配包括换行符在内的任何字符,就需要使用 [\s\S]
或 [^]
。现在,ES2020 中引入了 s
修饰符,它可以让 .
匹配包括换行符在内的任何字符。
示例代码:
const str = 'hello\nworld'; const re = /hello.world/s; console.log(re.test(str)); // true
2. y
修饰符
在 ES2015 中,引入了 u
修饰符,用于处理 Unicode 字符串。在 ES2020 中,又引入了 y
修饰符,用于执行“粘性”匹配。这意味着在匹配字符串时,只有从输入字符串的当前位置开始匹配才算成功。如果匹配失败,则不能回到之前的位置重新匹配。
示例代码:
const str = 'hello world'; const re = /hello/y; console.log(re.exec(str)); // ['hello'] console.log(re.exec(str)); // null
3. (?<name>)
语法
在 ES2018 中,引入了命名捕获组,用于捕获匹配的子字符串。在 ES2020 中,又引入了 (?<name>)
语法,用于给捕获组命名。
示例代码:
const str = '2020-01-01'; const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/; const match = re.exec(str); console.log(match.groups.year); // '2020' console.log(match.groups.month); // '01' console.log(match.groups.day); // '01'
优化建议
1. 避免使用不必要的捕获组
在正则表达式中,捕获组是用圆括号包围的子表达式。捕获组可以用于匹配和替换,但它们也会影响性能。因此,如果不需要捕获组,最好将其转换为非捕获组。
示例代码:
// 不必要的捕获组 const re1 = /(a)+/; console.log(re1.exec('aaaaa')); // ['aaaaa', 'a'] // 转换为非捕获组 const re2 = /(?:a)+/; console.log(re2.exec('aaaaa')); // ['aaaaa']
2. 避免使用回溯
回溯是指在匹配失败后,从之前的位置重新匹配。回溯会影响性能,因此尽量避免使用回溯。可以使用非贪婪量词或者将子表达式改写为非回溯形式来避免回溯。
示例代码:
// 使用非贪婪量词 const re1 = /".+?"/; console.log(re1.exec('"hello" "world"')); // ['"hello"'] // 改写为非回溯形式 const re2 = /"[^"]*"/; console.log(re2.exec('"hello" "world"')); // ['"hello"']
3. 避免重复编译正则表达式
正则表达式的编译是比较耗时的操作,因此尽量避免在循环中重复编译同一个正则表达式。可以将正则表达式编译成变量,然后在循环中重复使用。
示例代码:
-- -------------------- ---- ------- -- --------- --- ---- - - -- - - ---- ---- - ----- -- - ---------------------- ----- ----- - ---------------------- -- -- --------- - -- ----- ----- -- - ---------------------- --- ---- - - -- - - ---- ---- - ----- ----- - ---------------------- -- -- --------- -
结论
ECMAScript 2020 中引入了一些新的正则表达式特性,包括 s
修饰符、y
修饰符和 (?<name>)
语法。同时,我们也应该遵循一些优化建议,以提高正则表达式的性能。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/673be4c139d6d08e88b5bea2