为什么我不能在单词边界旁边使用重音字符?

Rex*_*ars 8 javascript regex unicode replace diacritics

我正在尝试制作一个与人名相匹配的动态正则表达式.它在大多数名称上都没有问题,直到我在名称的末尾遇到重音字符.

示例:一些FancyNamé

我到目前为止使用的正则表达式是:

/\b(Fancy Namé|Namé)\b/i
Run Code Online (Sandbox Code Playgroud)

像这样使用:

"Goal: Some Fancy Namé. Awesome.".replace(/\b(Fancy Namé|Namé)\b/i, '<a href="#">$1</a>');
Run Code Online (Sandbox Code Playgroud)

这根本不匹配.如果我用ae替换é,它就匹配得很好.如果我尝试匹配诸如"SomeFancyNaméa"这样的名字,它就可以了.如果我删除单词最后一个单词边界锚,它就可以正常工作.

为什么单词border flag不在这里工作?关于如何解决这个问题的任何建议?

我考虑过使用类似的东西,但我不确定性能惩罚会是什么样的:

"Some fancy namé. Allow me to ellaborate.".replace(/([\s.,!?])(fancy namé|namé)([\s.,!?]|$)/g, '$1<a href="#">$2</a>$3')
Run Code Online (Sandbox Code Playgroud)

建议?想法?

bob*_*nce 14

JavaScript的正则表达式实现不支持Unicode.它只知道标准低字节ASCII中的"单词字符",它不包括é任何其他重音或非英语字母.

因为éJS不是一个单词字符,é后面跟一个空格永远不能算是单词边界.(\b如果在单词的中间使用它会匹配,例如Namés.)

/([\s.,!?])(fancy namé|namé)([\s.,!?]|$)/

是的,这将是JS的常用解决方法(尽管可能有更多的标点字符).对于其他语言,你通常使用lookahead/lookbehind来避免匹配前后边界字符,但这些在JS中支持不足/错误,所以最好避免.


ken*_*ytm 7

罗布是对的.引自ECMAScript第3版:

15.10.2.6断言:

生产断言 \b评估...

2.调用IsWordChar(e-1)并使a成为布尔结果
3.调用IsWordChar(e)并将b作为布尔结果

内部帮助函数IsWordChar ...执行以下操作:

3.如果c是下表中的63个字符之一,则返回true.

a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9 _
Run Code Online (Sandbox Code Playgroud)

既然é不是这63个字符中的一个,之间的位置éa将被视为一个单词边界.

如果您知道字符类,则可以使用负前瞻断言,例如

/(^|[^\wÀ-ÖØ-öø-?])(Fancy Namé|Namé)(?![\wÀ-ÖØ-öø-?])/
Run Code Online (Sandbox Code Playgroud)