考虑以下大量 Unicode 正则表达式(表情符号代表非 ASCII 和额外 BMP 字符):
'🍤🍦🍋🍋🍦🍤'.match(/🍤|🍦|🍋/ug)
Firefox 返回 [ "🍤", "🍦", "🍋", "🍋", "🍦", "🍤"]
🤗。
Chrome 52.0.2743.116 和 Node 6.4.0 都返回 null
!它似乎并不关心我是否将字符串放入变量中并执行 str.match(…)
,也不关心我是否通过 new RegExp('🍤|🍦| 构建 RegExp 对象。 🍋', 'gu')
.
(Chrome 只需 ORing 两个 序列即可:'🍤🍦🍋🍋🍦🍤'.match(/🍤|🍦/ug)
也可以。可以使用非 Unicode:'aakkzzkkaa'.match(/aa|kk|zz/ug)
有效。)
我做错了吗?这是 Chrome 错误吗? ECMAScript compatibility table说我应该可以使用 Unicode 正则表达式。
(PS:本例中使用的三个表情符号只是替身。在我的应用程序中,它们将是任意但不同的字符串。但我想知道 '🍤🍦🍋🍋🍦🍤' .match(/[🍤🍦🍋]/ug)
适用于 Chrome 是否相关?)
更新标记为已修复 12 April 2017在 Chromium 和下游(包括 Chrome 和 Node)中。
最佳答案
没有 u
标志,您的正则表达式可以工作,这并不奇怪,因为在 BMP (=no "u") 模式下,它会将 16 位“单位”与 16 位“单位”,即另一个代理对的代理对。
“u”模式下的行为(应该比较代码点而不是单位)看起来确实像 Chrome 错误,同时您可以将每个替代方案包含在一个组中,这似乎工作正常:
m = '🍤🍦🍋🍋🍦🍤'.match(/(🍤)|(🍦)|(🍋)/ug)
console.log(m)
// note that the groups must be capturing!
// this doesn't work:
m = '🍤🍦🍋🍋🍦🍤'.match(/(?:🍤)|(?:🍦)|(?:🍋)/ug)
console.log(m)
这里有一个快速证明,在 u
模式下有两个以上的 SMP 替代方案被破坏:
// insert a whatever range
// from https://en.wikipedia.org/wiki/Plane_(Unicode)#Supplementary_Multilingual_Plane
var range = '11300-1137F';
range = range.split('-').map(x => parseInt(x, 16))
var chars = [];
for (var i = range[0]; i <= range[1]; i++) {
chars.push(String.fromCodePoint(i))
}
var str = chars.join('');
while(chars.length) {
var re = new RegExp(chars.join('|'), 'u')
if(str.match(re))
console.log(chars.length, re);
chars.pop();
}
在 Chrome 中,它只记录最后两个正则表达式(2 和 1 个 alt)。
关于javascript - Chrome ✗ vs Firefox 中 ES6/Unicode 正则表达式中的逻辑 OR 序列 ✓,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39152590/