Chrome 75正则表达式,“ S”匹配奇怪的unicode范围

时间:2019-06-07 18:16:13

标签: javascript google-chrome

我们在最新版本的Chrome(75)上遇到了一个奇怪的错误,该错误将S替换为S

console.log(
  'AZERTYUIOPQSDFGHJKLMWXCVBN'.replace(/[\u00A0-\u9999<>&]/gim, char => `&#${char.charCodeAt(0)};`)
)  

//AZERTYUIOPQ&#83;DFGHJKLMWXCVBN

有人知道代码是问题还是Chrome是问题?

4 个答案:

答案 0 :(得分:5)

已修复75.0.3770.142。


您发现了一个有趣的错误:

由于某些原因取决于不相关的字符范围,因此这两个测试是正确的:

> /[\u0178-\u017F]/i.test('s')
true
> /[\u0178-\u017F]/i.test('S')
true

https://chromium-review.googlesource.com/c/v8/v8/+/1478710(四月)介绍。

https://chromium-review.googlesource.com/c/v8/v8/+/1648098中的修复程序似乎相关,但是带有v8 7.7.27的Canary 77.0.3818.0仍然表现出此行为。这是一个单独的错误:https://crbug.com/971636

引入问题(https://bugs.chromium.org/p/v8/issues/detail?id=8348)的错误讨论了ECMAScript如何区别对待iu

  • i单独调用toUpperCase,它使用大小写 mapping
  • iu调用Unicode大小写折叠

这些稍有不同(尽管有此错误)。

我还发现了似乎是一个不同的错误:

这是一个小的测试用例,尽管v8中的修复程序涉及土耳其的案例折叠:

> text='ſ';
"ſ"
> new RegExp(text, 'i').test(text.toUpperCase())
true
> new RegExp(text, 'i').test('S')
false

它是在同一修订版中引入的,但它不是完全相同的错误。

答案 1 :(得分:0)

更改为:

'S'.replace(/[\u00A0-\u017E\u0180-\u9999<>&]/gim, char => `&#${char.charCodeAt(0)};`)

将避免使用\u017F的Unicode字符“拉丁小写字母长S”。这只是一个解决方法。

触发范围的另一端似乎是\u0073,即“拉丁文小写字母S”。

答案 2 :(得分:0)

在该间隔中甚至不使用标志im,并且您需要使用标志u 将模式视为Unicode代码点的序列。

console.log(
  'AZERTYUIOPQSDFGHJKLMWXCVBN'.replace(/[\u00A0-\u9999<>&]/gu, char => `&#${char.charCodeAt(0)};`)
) 

答案 3 :(得分:0)

我在Chrome 75中看到了相同的问题,但在Chrome 74中却没有。通过使用以下正则表达式可以解决此问题:

'AZERTYUIOPQSDFGHJKLMWXCVBN'.replace(/[\u00A0-\u9999<>&]/g, char => `&#${char.charCodeAt(0)};`)

如某些评论中所述,我认为您不需要i,u或m修饰符。