如何在JavaScript中执行不区分大小写的字符串比较?


当前回答

编辑:这个答案最初是9年前添加的。现在你应该使用带有sensitivity: 'accent'选项的localeCompare:

函数ciEquals(a, b) { 返回typeof a === 'string' && typeof b === 'string' ? a.localeCompare(b, undefined, {sensitivity: 'accent'}) === 0 : a === b; } console.log("'a' = 'a'?", ciEquals('a', 'a')); console.log(“' AaA ' = ' AaA ' ?”,ciEquals (' AaA ', ' AaA ')); console.log("'a' = 'á'?", ciEquals('a', 'á')); console.log("'a' = 'b'?", ciEquals('a', 'b'));

{sensitivity: 'accent'}告诉localeCompare()将相同基字母的两个变体视为相同的,除非它们具有不同的重音(如上面的第三个例子)。

或者,您可以使用{sensitivity: 'base'},只要两个字符的基本字符相同,就将它们视为等效字符(因此A将被视为等效á)。

请注意,localeCompare的第三个参数在IE10或更低版本或某些移动浏览器中不受支持(请参阅上面链接页面上的兼容性图表),所以如果你需要支持这些浏览器,你将需要某种退步:

function ciEqualsInner(a, b) {
    return a.localeCompare(b, undefined, { sensitivity: 'accent' }) === 0;
}

function ciEquals(a, b) {
    if (typeof a !== 'string' || typeof b !== 'string') {
        return a === b;
    }

    //      v--- feature detection
    return ciEqualsInner('A', 'a')
        ? ciEqualsInner(a, b)
        : /*  fallback approach here  */;
}

原来的答案

在JavaScript中进行不区分大小写比较的最好方法是使用RegExp match()方法和i标志。

不区分大小写的搜索

当两个被比较的字符串都是变量(而不是常量)时,这就有点复杂了,因为你需要从字符串中生成一个RegExp,但是如果字符串中有特殊的regex字符,将字符串传递给RegExp构造函数可能会导致不正确的匹配或失败的匹配。

如果你关心国际化,不要使用toLowerCase()或toUpperCase(),因为它不能在所有语言中提供准确的不区分大小写的比较。

http://www.i18nguy.com/unicode/turkish-i18n.html

其他回答

更新:

根据注释,之前的答案检查源包含关键字,使其相等检查添加了^和$。

(/^keyword$/i).test(source)

借助于正则表达式也可以实现。

(/keyword/i).test(source)

/i表示忽略大小写。如果没有必要,我们可以忽略并测试not大小写敏感匹配

(/keyword/).test(source)

将两者转换为更低的字符串(出于性能原因,只进行一次),并将它们与内联三元运算符进行比较:

function strcasecmp(s1,s2){
    s1=(s1+'').toLowerCase();
    s2=(s2+'').toLowerCase();
    return s1>s2?1:(s1<s2?-1:0);
}

假设我们想要在字符串变量大海捞针。这里有三个陷阱:

国际化的应用程序应该避免字符串。toUpperCase和string.toLowerCase。请使用忽略大小写的正则表达式。例如,var needleRegExp = new RegExp(needle, "i");然后是needleRegExp.test(haystack)。 一般来说,你可能不知道针的价值。注意针头不包含任何正则表达式特殊字符。使用needle.replace(/[-[\]{}()*+?, \ \ ^ $ | # \] / g , "\\$&");. 在其他情况下,如果您想精确匹配needle和haystack,只需忽略case,请确保在正则表达式构造函数的开头添加“^”,并在末尾添加“$”。

考虑到第(1)和(2)点,一个例子是:

var haystack = "A. BAIL. Of. Hay.";
var needle = "bail.";
var needleRegExp = new RegExp(needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), "i");
var result = needleRegExp.test(haystack);
if (result) {
    // Your code here
}

不抛出异常和不使用慢正则表达式怎么样?

return str1 != null && str2 != null 
    && typeof str1 === 'string' && typeof str2 === 'string'
    && str1.toUpperCase() === str2.toUpperCase();

上面的代码段假设您不希望匹配任何一个字符串为null或undefined。

如果你想匹配null/undefined,那么:

return (str1 == null && str2 == null)
    || (str1 != null && str2 != null 
        && typeof str1 === 'string' && typeof str2 === 'string'
        && str1.toUpperCase() === str2.toUpperCase());

如果出于某种原因你关心undefined vs null:

return (str1 === undefined && str2 === undefined)
    || (str1 === null && str2 === null)
    || (str1 != null && str2 != null 
        && typeof str1 === 'string' && typeof str2 === 'string'
        && str1.toUpperCase() === str2.toUpperCase());

这里有很多答案,但我喜欢添加一个基于扩展String库的解决方案:

String.prototype.equalIgnoreCase = function(str)
{
    return (str != null 
            && typeof str === 'string'
            && this.toUpperCase() === str.toUpperCase());
}

这样你就可以像在Java中那样使用它!

例子:

var a = "hello";
var b = "HeLLo";
var c = "world";

if (a.equalIgnoreCase(b)) {
    document.write("a == b");
}
if (a.equalIgnoreCase(c)) {
    document.write("a == c");
}
if (!b.equalIgnoreCase(c)) {
    document.write("b != c");
}

输出将是:

"a == b"
"b != c"

String.prototype.equalIgnoreCase = function(str) { 返回(str != null && Typeof STR === 'string' && this.toUpperCase() === str.toUpperCase()); } Var a = "hello"; var b = "HeLLo"; Var c = "world"; if (a.equalIgnoreCase(b)) { 文档。写("a == b"); document . write(“< br > "); } if (a.equalIgnoreCase(c)) { 文档。写("a == c"); } if (!b.equalIgnoreCase(c)) { 文档。写("b != c"); }