Chrome✗和Firefox中的ES6 / Unicode正则expression式中的逻辑或序列✓

考虑下面的Unicode重正则expression式(表情符号代表非ASCII和额外的BMP字符):

'🍤🍦🍋🍋🍦🍤'.match(/🍤|🍦|🍋/ug) 

Firefox返回[ "🍤", "🍦", "🍋", "🍋", "🍦", "🍤" ] 🤗。

Chrome 52.0.2743.116和节点6.4.0都返回null ! 如果我把string放在一个variables中,并且执行str.match(…) ,也不关心我是否通过new RegExp('🍤|🍦|🍋', 'gu')一个RegExp对象。

(Chrome可以用ORing 两个序列来确定: '🍤🍦🍋🍋🍦🍤'.match(/🍤|🍦/ug)可以,非Unicode也可以: 'aakkzzkkaa'.match(/aa|kk|zz/ug)作品。)

难道我做错了什么? 这是一个Chrome的错误? ECMAScript兼容性表格说,我应该与Unicode正则expression式确定。

(PS:在这个例子中使用的三个表情符号就是stand-ins,在我的应用程序中,它们是任意的但是不同的string,但是我想知道'🍤🍦🍋🍋🍦🍤'.match(/[🍤🍦🍋]/ug)在Chrome中工作是相关的?)

没有u标志,你的正则expression式就起作用了,这也就不足为奇了,因为在BMP(= no“u”)模式下,它比较16位“单位”和16位“单位”,也就是说,另一个代理对。

“u”模式下的行为(应该比较代码点而不是单元)看起来确实像一个Chrome的bug,同时你可以将每个选项放在一个组中,这似乎工作正常:

 m = '🍤🍦🍋🍋🍦🍤'.match(/(🍤)|(🍦)|(🍋)/ug) console.log(m) // note that the groups must be capturing! // this doesn't work: m = '🍤🍦🍋🍋🍦🍤'.match(/(?:🍤)|(?:🍦)|(?:🍋)/ug) console.log(m) 

没有“u”标志,它也适用于chrome(52.0.2743.116)

好吧,标志似乎被打破了

除非你使用乘数'🍤🍤🍦🍦🍦🍦🍋🍋🍋🍋🍦🍦🍦🍦🍤🍤'.match(/🍤|🍦{2}|🍋/g) – > null {1}{1,}似乎工作,我假设他们被翻译成? 和+。 我假设没有“u”标志🍦{2}被解释为\ud83c\udf66{2} ,这将解释行为。

刚刚用(?:🍦){2}进行testing,这似乎是正确的。 我想这证实了我对乘数的假设。

这里快速解决这个问题:

 //a utility I usually have in my codes var replace = (pattern, replacement) => value => String(value).replace(pattern, replacement); var fixRegexSource = replace( /[\ud800-\udbff][\udc00-\udfff]/g, //"(?:$&)" //not sure wether this might still be buggy //that's why I convert it into the unicode-syntax, //this can't be misinterpreted c => `(?:\\u${c.charCodeAt(0).toString(16)}\\u${c.charCodeAt(1).toString(16)})` ); var fixRegex = regex => new RegExp( fixRegexSource(regex.source), regex.flags.replace("u", "") ); 

sry,没有拿出更好的function名称