如果我从中获取一些希腊月份名称并从中制作不区分大小写的正则表达式,它们将不会以大写形式匹配同一月份:
<!doctype html>
<html>
<head>
</head>
<body>
<pre></pre>
<script>
var names = [
'Μάρτιος',
'Μάιος',
'Ιούνιος',
'Ιούλιος',
'Αύγουστος',
'Νοέμβριος'
];
var pre = document.getElementsByTagName('pre')[0];
var i;
for (i = 0; i < names.length; ++i) {
var m = names[i];
var r = new RegExp(m, 'i');
pre.innerHTML += m + ' ' + r.test(m.toLocaleUpperCase()) + 'n';
}
</script>
</body>
</html>
在 Ie8 中,这会打印名称,然后打印 false。在其他浏览器中,它打印为 true。
只需使用 .toUpperCase()
而不是 .toLocaleUpperCase()
即可。
后者将Μάρτιος
翻译成ΜΆΡΤΙΟΣ
,前者将其翻译成ΜΆΡΤΙΟς
。
不过,我不能说哪个变体是正确的,因为我不知道ς
的大写规则.
好吧,我所有可用的IE版本Μάρτιος
总是转换为ΜΆΡΤΙΟς
,即使使用.toUpperCase()
。
我认为问题是某些字母(http://de.wikipedia.org/wiki/Griechisches_Alphabet#Klassische_Zeichen)的变体。
例如,字母Σ σ Σ和ς都是"Sigma"。前两个都是经典的,另一个是变体。另一个例子是 Β、β 和 β 表示"Beta"。
为了确保识别这些变体,我建议在创建正则表达式之前进行替换。
在这里,我做了一个简短的(可能不完整的)辅助函数来执行此操作
function regextendVariants(s)
{
var variants = [
['β', 'ϐ'],
['ε', 'ϵ'],
['θ', 'ϑ'],
['κ', 'ϰ'],
['π', 'ϖ'],
['ρ', 'ϱ'],
['σ', 'Ϲ', 'ς'],
['φ', 'ϕ']
];
for (var j = 0; j < variants.length; j++) {
var variant = variants[j];
for (var k = 1; k < variant.length; k++) {
s = s.replace(variant[k], '['+variant.join('')+']');
}
}
return s;
}
此函数将字符串转换为
- Μάρτιο[σΣς]
- Μάιο[σΣς]
- Ιούνιο[σΣς]
- Ιούλιο[σΣς]
- Αύγουστο[σΣς]
- Νοέμβριο[σΣς]
这些字符串允许同一字母的不同变体。我敢肯定,这在语法上是不正确的,但它应该更可靠以匹配字符串。
在你的代码中,你必须替换
var r = new RegExp(m, 'i');
跟
var r = new RegExp(regextendVariants(m), 'i');
正如我所说,我的IE版本不会出错,所以我不能向您保证这将是您问题的最终解决方案,我希望它是;)
ς
以UTF-8 或 U+03C2
xCFx82
作为自 Unicode 1.1 以来一直存在的 Unicode 代码点的十六进制值。
SpecialCasing.txt
中的 Unicode 字符数据 (UCD) 条目是:
# <code>; <lower> ; <title> ; <upper> ; (<condition_list> ;)? # <comment>
03A3; 03C2; 03A3; 03A3; Final_Sigma; # GREEK CAPITAL LETTER SIGMA
其中U+03A3
是希腊大写字母西格玛(Σ
)。这至少可以追溯到Unicode 2.1 Update 3(http://www.unicode.org/Public/2.1-Update3/SpecialCasing-1.txt),因此IE8应该支持大小写映射。
因此,Σ
是ς
的正确大写。
toUpperCase和toLocaleUpperCase函数的MSDN文档说两者都使用Unicode大小写映射。如果与当前系统区域设置冲突(例如,对于某些土耳其语映射),toLocaleUpperCase
函数将使用系统区域设置大小写映射。因此,如果您只需要 Unicode 大小写映射,则应使用 toUpperCase
.