为什么这个正则表达式对德语单词无法工作?
为什么这个正则表达式对德语单词无法工作?
我试图将以下句子分解成单词,并将它们用标签包裹起来。
我按照以下方式操作:
$('p').each(function() {
var $this = $(this);
$this.html($this.text().replace(/\b(\w+)\b/g, "$1"));
});
唯一的问题是,在将单词用标签包裹后,结果的HTML看起来像这样:
Das ist ein schönes Armband
所以,"schönes" 被拆分为三个单词 "sch"、"ö" 和 "nes"。为什么会发生这种情况?正确的正则表达式是什么?
为什么这个正则表达式不能匹配德语单词?
问题原因:这个正则表达式 \w
只能匹配 A-Z、a-z、0-9 和下划线。对于包括如 ö 在内的非 ASCII 字符,它无法匹配。
解决方法:可以使用类似 \S+
的表达式来匹配所有非空格字符,包括非 ASCII 字符。这可能会或可能不会成功,具体取决于字符串的其余格式。
参考链接:http://www.javascriptkit.com/javatutors/redev2.shtml
修正后的代码应为:$this.text().replace(/\b(\S+)\b/g, "<span>$1</span>")
注意:与 \w+
不同,\S+
还会匹配单词末尾的句点、逗号等标点符号。因此,如果使用这个正则表达式解析这个评论,第一个匹配项将是 "Note:" 而不是 "Note"。如果不希望这样,您需要调整您的正则表达式或执行其他检查。
为什么这个正则表达式不能匹配德语单词?
问题出现的原因是Javascript的正则表达式中的\w、\d和\b快捷方式不支持Unicode。这是Java和Javascript中的一个bug,这个限制在21世纪是没有意义的。Javascript也不支持任何Unicode属性。
解决方法是,可以使用\pL代替\w来匹配任何具有Unicode General_Category=Letter属性的字符,这样可以模拟一个正确的\w。在Java中可以使用[\pL\p{Nd}_]来实现,但是在Javascript中似乎没有这个解决方法。另外,Ruby、Python、Perl和PCRE都提供了扩展\w的方法,但是Javascript没有。
Java目前只支持一到两个字符的常见属性,如\pN和\p{Lu},不支持像\p{IsGreek}这样的脚本属性。未来的JDK7将会添加脚本属性,但是仍然不支持大多数Unicode属性。
相比之下,Perl对Unicode属性的支持非常丰富,Java和Javascript都远远不及。Javascript几乎不支持任何Unicode属性,这使得它在处理Unicode时几乎无法使用。
,Javascript的正则表达式不支持Unicode属性,导致无法正确匹配德语单词。解决方法是使用其他语言或者使用Java的\pL来模拟\w。