关于国际化:在javascript中使用tolowercase或touppercase比较字符串更好吗?

Is it better to compare strings using toLowerCase or toUpperCase in JavaScript?

我正在进行一次代码审查,我很好奇在尝试比较字符串时,在忽略大小写的情况下,是否最好在JavaScript中将字符串转换为大写或小写。

简单的例子:

1
2
3
var firstString ="I might be A different CASE";
var secondString ="i might be a different case";
var areStringsEqual = firstString.toLowerCase() === secondString.toLowerCase();

或者我应该这样做:

1
2
3
var firstString ="I might be A different CASE";
var secondString ="i might be a different case";
var areStringsEqual = firstString.toUpperCase() === secondString.toUpperCase();

它似乎要么是"应该"的,要么只与英语字母这样的有限字符集一起使用,所以它一个比另一个更强大?

请注意,msdn建议将字符串规范化为大写,但这是针对托管代码(可能是C&;F,但它们具有奇特的字符串比较器和基库):http://msdn.microsoft.com/en-us/library/bb386042.aspx


修订答案

我回答这个问题已经很久了。虽然文化问题仍然存在(我认为它们永远不会消失),但ECMA-402标准的发展使我得到了最初的答案…过时(或过时?).

比较本地化字符串的最佳解决方案似乎是使用带有适当区域设置和选项的函数localeCompare()

1
2
3
4
5
6
var locale = 'en'; // that should be somehow detected and passed on to JS
var firstString ="I might be A different CASE";
var secondString ="i might be a different case";
if (firstString.localeCompare(secondString, locale, {sensitivity: 'accent'}) === 0) {
    // do something when equal
}

这将比较两个不区分大小写但区分重音的字符串(例如? != a).
If this is not sufficient for performance reasons, you may want to use either
tolocaleuppercase()ortolocalelowercase()`将区域设置作为参数传递:

1
2
3
if (firstString.toLocaleUpperCase(locale) === secondString.toLocaleUpperCase(locale)) {
    // do something when equal
}

理论上应该没有区别。在实践中,细微的实现细节(或者在给定的浏览器中缺乏实现)可能会产生不同的结果…

原始答案

我不确定您是否真的打算在国际化(i18n)标签中问这个问题,但是既然您这样做了…或许最出人意料的答案是:两者都不是。

大小写转换有很多问题,如果您想转换字符大小写而不指示语言(如javascript大小写),这不可避免地会导致功能问题。例如:

  • 有许多自然语言没有大小写字符的概念。尝试转换它们是没有意义的(尽管这是可行的)。
  • 有特定于语言的字符串转换规则。德文夏普S字(?)必须转换为两个大写的S字母(SS)。
  • 土耳其语和阿塞拜疆语(或阿塞拜疆,如果你愿意的话)有"非常奇怪"的两个I字概念:无点?(哪个转换为大写I)和点式I(哪个转换为大写?<-此字体不允许正确的表示,但这确实是不同的字形)。
  • 希腊语有许多"奇怪"的转换规则。关于大写字母sigma(∑)的一个特殊规则,它取决于单词中的位置,有两个小写对应词:正则sigma(σ)和最终sigma(?).对于"重音"字符也有其他转换规则,但在转换函数的实现过程中通常会忽略这些规则。
  • 有些语言有标题字母,即?哪些应该转换成类似的东西?或者不太合适的LJ。结扎也是如此。
  • 最后,有许多兼容字符的含义可能与您试图比较的内容相同,但它们是由完全不同的字符组成的。更糟的是,"ae"可能等同于"?"德语和芬兰语,但相当于"?"在丹麦。
  • 我试图说服您,比较用户输入的字面意思,而不是转换它,这真的更好。如果它与用户无关,可能并不重要,但案例转换总是需要时间。何苦?


    它从不依赖于浏览器,因为它只是涉及到的javascript。两者都将根据需要更改的字符数提供性能(翻转大小写)

    1
    2
    var areStringsEqual = firstString.toLowerCase() === secondString.toLowerCase();
    var areStringsEqual = firstString.toUpperCase() === secondString.toUpperCase();

    如果您使用由@adeneo准备的测试,您可以感觉到它依赖于浏览器,但可以进行一些其他测试输入,如"aaaaaaaaaaaaaaaaaaaaaaaaaa"&;"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"并进行比较。

    Javascript的性能取决于浏览器是否存在某些dom API或任何dom操作/交互,否则对于所有普通的Javascript,它将提供相同的性能。