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名称