JavaScript不区分大小写的字符串比较

fly*_*ire 963 javascript string

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

SLa*_*aks 1081

最简单的方法(如果你不担心特殊的Unicode字符)是调用toUpperCase:

var areEqual = string1.toUpperCase() === string2.toUpperCase();
Run Code Online (Sandbox Code Playgroud)

  • 是否有理由更喜欢`toUpperCase`而不是`toLowerCase`? (128认同)
  • @ jpmc26:是的; http://msdn.microsoft.com/en-us/library/bb386042.aspx和http://en.wikipedia.org/wiki/Capital_%E1%BA%9E (125认同)
  • @sam:我知道.这就是为什么我写"如果你不担心特殊的Unicode字符". (54认同)
  • 转换为大写或小写确实可以在所有语言中提供正确的不区分大小写的比较.http://www.i18nguy.com/unicode/turkish-i18n.html (42认同)
  • 这真的是JS提供的最好的吗? (13认同)
  • 社区是否可以努力使这不是第一个/接受的答案,因为它只是“错误的”。并且仅在非常特定的情况下而不是一般情况下正确。 (5认同)
  • @Kugel这个答案今年9岁。从那时起,就有了新功能,因此截至您发表评论的日期,不是,这不是JS所能提供的最好的功能。请参阅以下有关“ localeCompare”的答案,该答案最近更新了(但仍在五年前)。我不知道在过去五年中发生了什么变化,这些变化将使localeCompare不再是最佳答案。 (4认同)
  • @SLaks:我没有得到“toUpperCase”的 MS 参数提到“往返”。ẞ(大写)和 ß(小写)都无法完成往返。那么对其中之一的偏好是如何从中得出的呢? (3认同)
  • 你是什​​么意思"如果你不担心特殊的Unicode字符"?toUpperCase对这个字符有什么影响? (2认同)
  • 'ß'.toUpperCase() 将字符串转换为 `SS`。哇,没想到。在我看来,“ß”不应该改变。但为此我更喜欢使用 LowerCase() 进行不区分大小写的检查。 (2认同)

Sam*_*eff 182

编辑:这个答案最初是在9年前添加的.今天,你应该使用localeComparesensitivity: 'accent'选项:

function ciEquals(a, b) {
    return 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'));
Run Code Online (Sandbox Code Playgroud)

{ sensitivity: 'accent' }告诉localeCompare()治疗相同基础函作为相同的两个变体,除非以上它们具有不同的重音符号(如在第三示例).

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

请注意,localeCompareIE10或更低版本或某些移动浏览器不支持第三个参数(请参阅上面链接的页面上的兼容性图表),因此如果您需要支持这些浏览器,则需要某种后备:

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  */;
}
Run Code Online (Sandbox Code Playgroud)

原始答案

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

不区分大小写的搜索

当比较的两个字符串都是变量(不是常量)时,它会有点复杂'因为你需要从字符串生成一个RegExp但是将字符串传递给RegExp构造函数会导致错误的匹配或者如果字符串有特殊的正则表达式则匹配失败其中的人物.

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

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

  • 对于不区分大小写的字符串比较,使用它是最昂贵的解决方案.RegExp用于复杂的模式匹配,因此,它需要为每个模式构建决策树,然后针对输入字符串执行该决策树.虽然它可行,但它可以与乘坐喷气式飞机在下一个街区购物相媲美.tl;博士:请不要这样做. (19认同)
  • @Quandary,是的,这就是我所说的必须处理的 - "你需要从字符串生成一个RegExp,但是如果字符串中有特殊的正则表达式字符,那么将字符串传递给RegExp构造函数会导致匹配错误或匹配失败" (5认同)
  • @StingyJack使用localeCompare进行不区分大小写的比较,你应该做'a'.localeCompare('A',undefined,{sensitivity:'base'}) (3认同)
  • 我可以使用localeCompare(),但它返回-1为''a'.localeCompare('A')`和op我正在寻找不区分大小写的字符串比较. (2认同)
  • **注意:** `localeCompare` 版本要求 JavaScript 引擎支持 [ECMAScript® 国际化 API](https://ecma-international.org/ecma-402/6.0/index.html),它是 * *不是**需要做的。因此,在依赖它之前,您可能需要检查它是否适用于您正在使用的环境。例如: `const CompareInsensitive = "x".localeCompare("X", undefined, {sensitivity: "base"}) === 0 ?(a, b) => a.localeCompare(b, undefined, {sensitivity: "base"}) : (a, b) => a.toLowerCase().localeCompare(b.toLowerCase());` 或类似的。 (2认同)

SP0*_*007 32

在正则表达式的帮助下我们也可以实现.

(/keyword/i).test(source)
Run Code Online (Sandbox Code Playgroud)

/i是为了忽略大小写.如果没有必要,我们可以忽略并测试非区分大小写的匹配

(/keyword/).test(source)
Run Code Online (Sandbox Code Playgroud)

  • 使用这样的正则表达式将匹配子串!在您的示例中,字符串`keyWORD`将使indead导致正匹配.但字符串`这是关键字yo`或`keywords`也会产生正匹配.请注意:-) (16认同)
  • 这不能回答问题中所要求的“等于”检查(不区分大小写)!但是,这是“包含”检查!不要用 (6认同)
  • 当然,要匹配整个字符串,可以将regexp更改为`/ ^ keyword $ /。test(source)`,但是1)如果`keyword'不是常量,则需要执行`new RegExp( '^'+ x +'$')。test(source)`和2)依靠正则表达式来测试诸如不区分大小写的字符串相等之类的简单操作根本不是很有效。 (3认同)

jay*_*jay 28

正如最近的评论所说,string::localCompare支持不区分大小写的比较(以及其他强大的东西).

这是一个简单的例子

'xyz'.localeCompare('XyZ', undefined, { sensitivity: 'base' }); // returns 0
Run Code Online (Sandbox Code Playgroud)

还有一个你可以使用的通用功能

function equalsIgnoringCase(text, other) {
    return text.localeCompare(other, undefined, { sensitivity: 'base' }) === 0;
}
Run Code Online (Sandbox Code Playgroud)

请注意,undefined您应该输入您正在使用的特定区域设置,而不是您.这很重要,如MDN文档中所述

瑞典语,ä和a是单独的基本字母

灵敏度选项

灵敏度选项从MDN制表

浏览器支持

截至发布时,Android浏览器和Opera Mini 支持区域设置选项参数.请查看https://caniuse.com/#search=localeCompare以获取最新信息.


Shi*_*hah 26

请记住,大小写是特定于语言环境的操作.根据具体情况,您可能希望将其纳入帐户.例如,如果要比较两个人的名字,可能需要考虑区域设置,但如果要比较机器生成的值(如UUID),则可能不会.这就是为什么我在我的utils库中使用以下函数(请注意,出于性能原因,不包括类型检查).

function compareStrings (string1, string2, ignoreCase, useLocale) {
    if (ignoreCase) {
        if (useLocale) {
            string1 = string1.toLocaleLowerCase();
            string2 = string2.toLocaleLowerCase();
        }
        else {
            string1 = string1.toLowerCase();
            string2 = string2.toLowerCase();
        }
    }

    return string1 === string2;
}
Run Code Online (Sandbox Code Playgroud)


Nic*_*sev 13

我最近创建了一个提供不区分大小写的字符串帮助程序的微库:https://github.com/nickuraltsev/ignore-case.(它在toUpperCase内部使用.)

var ignoreCase = require('ignore-case');

ignoreCase.equals('FOO', 'Foo'); // => true
ignoreCase.startsWith('foobar', 'FOO'); // => true
ignoreCase.endsWith('foobar', 'BaR'); // => true
ignoreCase.includes('AbCd', 'c'); // => true
ignoreCase.indexOf('AbCd', 'c'); // => 2
Run Code Online (Sandbox Code Playgroud)


Jas*_*sen 11

如果你担心不等式的方向(也许你想要对列表进行排序),你几乎必须进行大小写转换,因为unicode中的小写字符比大写toLowerCase更多可能是最好的转换.

function my_strcasecmp( a, b ) 
{
    if((a+'').toLowerCase() > (b+'').toLowerCase()) return 1  
    if((a+'').toLowerCase() < (b+'').toLowerCase()) return -1
    return 0
}
Run Code Online (Sandbox Code Playgroud)

Javascript似乎使用区域设置"C"进行字符串比较,因此如果字符串包含非ASCII字母,则生成的顺序将是丑陋的.如果不对字符串进行更详细的检查,就没有太多可以做的.


Chr*_*ute 7

假设我们想在字符串变量needle中找到字符串变量haystack.有三个问题:

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

考虑点(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
}
Run Code Online (Sandbox Code Playgroud)


Neb*_*sar 6

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

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

这样您就可以像在 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");
}
Run Code Online (Sandbox Code Playgroud)

输出将是:

"a == b"
"b != c"
Run Code Online (Sandbox Code Playgroud)

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


小智 6

使用 RegEx 进行字符串匹配或比较。

在 JavaScript 中,可以match()用于字符串比较,不要忘记放入iRegEx。

例子:

var matchString = "Test";
if (matchString.match(/test/i)) {
  alert('String matched');
}
else {
 alert('String not matched');
}
Run Code Online (Sandbox Code Playgroud)

  • 确保您可以接受部分匹配,否则“matchString.match(/^test$/i)”。 (2认同)

Ale*_*mov 6

如果两个字符串具有相同的已知区域设置,您可能需要使用Intl.Collator如下对象:

function equalIgnoreCase(s1: string, s2: string) {
    return new Intl.Collator("en-US", { sensitivity: "base" }).compare(s1, s2) === 0;
}
Run Code Online (Sandbox Code Playgroud)

显然,您可能希望缓存Collator以提高效率。

这种方法的优点是它比使用 RegExp 快得多,并且基于高度可定制的(请参阅上面文章中的构造函数参数的描述localesoptions一组即用型整理器。


小智 5

不区分大小写的比较有两种方式:

  1. 将字符串转换为大写,然后使用严格运算符 ( ===)进行比较。严格运算符如何处理操作数读取内容:http : //www.thesstech.com/javascript/relational-logical-operators
  2. 使用字符串方法进行模式匹配:

使用“搜索”字符串方法进行不区分大小写的搜索。阅读有关搜索和其他字符串方法的信息:http : //www.thesstech.com/pattern-matching-using-string-methods

<!doctype html>
  <html>
    <head>
      <script>

        // 1st way

        var a = "apple";
        var b = "APPLE";  
        if (a.toUpperCase() === b.toUpperCase()) {
          alert("equal");
        }

        //2nd way

        var a = " Null and void";
        document.write(a.search(/null/i)); 

      </script>
    </head>
</html>
Run Code Online (Sandbox Code Playgroud)


Jav*_*eak 5

我喜欢这种快速速记变化 -

export const equalsIgnoreCase = (str1, str2) => {
    return (!str1 && !str2) || (str1 && str2 && str1.toUpperCase() == str2.toUpperCase())
}
Run Code Online (Sandbox Code Playgroud)

处理速度快,并且能达到预期的效果。