带有\b和国际字符的Javascript正则表达式问题

Posted

技术标签:

【中文标题】带有\\b和国际字符的Javascript正则表达式问题【英文标题】:Javascript regular expression problem with \b and international characters带有\b和国际字符的Javascript正则表达式问题 【发布时间】:2011-07-15 18:14:20 【问题描述】:

我在使用简单的正则表达式匹配时遇到了很多问题。

我有这个带有重音字符的字符串(这只是一个例子)"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”,它会按预期工作。 如果您尝试在中间匹配带有重音的单词,它会按预期工作。 但是,如果您尝试匹配末尾带有重音的单词,则会失败。

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

【问题讨论】:

【参考方案1】:

不幸的是,javascript 中的速记字符类不支持 unicode(甚至是高位 ASCII)。

看看这个问题的答案:Javascript + Unicode。这篇文章链接在那个问题JavaScript, Regex, and Unicode 中,说\b 是由一个单词边界定义的,它被定义为:

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

因此,它适用于结尾带有 A-Z, a-z, 0-9, and _ 的单词,但不适用于结尾带有重音字符的单词。

【讨论】:

所以它适用于结尾有重音的单词,但不适用于结尾有重音的单词。 ? 至少在 Chromium 中,.toUpperCase().toLowerCase() 似乎对 unicode 非常友好,所以理论上 c.toUpperCase() != c || c.toLowerCase() != c 应该对属于“大小写字母”的字符进行测试(仍然没有'不涵盖所有“单词边界”。)是否有一些官方主列表或数据库,其中 unicode 字形应被视为 alpha?【参考方案2】:

来自 ES3 规范:

内部辅助函数 IsWordChar 采用整数参数 e 并执行以下操作:

    如果 e == –1 或 e == InputLength,则返回 false。 设 c 为字符 Input[e]。

    如果 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 _
    

    返回 false。

“IsWordChar()”内部(可能是假设的)函数是“\b”断言的行为基础。

edit — 在 ES5 中也好不到哪里去。

【讨论】:

以上是关于带有\b和国际字符的Javascript正则表达式问题的主要内容,如果未能解决你的问题,请参考以下文章

如何在正则表达式中使用带有字符的“环视”来捕获整个字符串?

javascript正则表达式

JavaScript正则表达式二

JavaScript正则表达式

如何检测带有下划线的字符串的正则表达式模式

javascript正则表达式