JavaScript正则表达式\b和国际字符的问题

13
我在进行简单的正则表达式匹配时遇到了很多问题。
我有一个包含重音符号的字符串(这只是一个示例)"Botó Entrepà Nadó Facebook!",我想使用来自另一个列表的单词来匹配单词。
这是我的代码的简化版本。例如,要匹配"Botó"。
var matchExpr = new RegExp ('\\b' + 'Botó' + '\\b','i'); 
"Botó Entrepà Nadó Facebook! ".match(matchExpr);

如果我运行它,它不会像预期的那样匹配"Botó" (在Firefox、IE和Chrome中)。

我以为这是我的错误。但是接下来就有趣了...

如果我像这样修改字符串 "Botón Entrepà Nadó Facebook! " (注意 "Botó" 后面的 "n"),然后再运行相同的代码:

var matchExpr = new RegExp ('\\b' + 'Botó' + '\\b','i'); 
"Botón Entrepà Nadó Facebook! ".match(matchExpr);

它匹配了 "Botó"!!!!????? (至少在Firefox中)。 对我来说,这没有意义,因为"n"不是一个单词边界(与\b匹配的内容)。

如果你尝试匹配整个单词:

var matchExpr = new RegExp ('\\b' + 'Botón' + '\\b','i'); 
"Botón Entrepà Nadó Facebook! ".match(matchExpr);

它有效。

为了让它变得更加奇怪,我们在末尾添加另一个带重音的字母。

var matchExpr = new RegExp ('\\b' + 'Botóñ' + '\\b','i'); 
"Botóñ Entrepà Nadó Facebook! ".match(matchExpr);

如果我们尝试匹配这个,它将不会匹配任何内容。但是,如果我们尝试这样:

var matchExpr = new RegExp ('\\b' + 'Botóñ' + '\\b','i'); 
"Botóña Entrepà Nadó Facebook! ".match(matchExpr);

它匹配了 "Botóñ",但这是错误的。

如果我们尝试匹配 "Facebook",则正常工作。 如果你尝试匹配中间带有重音符号的单词,它也能正常工作。 但如果您尝试匹配以重音符号结尾的单词,则失败。

我做错了什么?这是预期的行为吗?

2个回答

5
很遗憾,Javascript中的简写字符类不支持Unicode(甚至不支持高ASCII)。请参考这个问题的答案:Javascript + Unicode。该问题链接的文章JavaScript, Regex, and Unicode指出,\b定义为单词边界,其定义如下:

→ 单词字符 — 仅包括A-Z、a-z、0-9和_字符。
→ 单词边界 — 单词字符与非单词字符之间的位置。

因此,它可以匹配以A-Z,a-z,0-9和_结尾的单词,但无法匹配以重音符结尾的单词。

因此,它将适用于以重音结尾的单词,但不适用于以重音结尾的单词。 - Felix Kling
在Chromium中,至少.toUpperCase().toLowerCase()似乎相当友好于Unicode,因此在理论上,c.toUpperCase()!= c || c.toLowerCase()!= c应该为“带大小写字母的字母表”的成员字符测试为真(这仍然不包括所有“单词边界”)。是否有一些官方的主要列表或数据库可以确定哪些Unicode字形应被视为字母? - Lori

3

来自于ES3规范:

内部辅助函数IsWordChar接收一个整型参数e并执行以下操作:

  1. If e == –1 or e == InputLength, return false.
  2. Let c be the character Input[e].
  3. If c is one of the sixty-three characters in the table below, return 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 _
    
  4. Return false.

"IsWordChar()"是内部(可能是假设的)函数,它是"\b"断言行为的基础。
编辑-在ES5中也没有改善。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接