JavaScript case insensitive string comparison
如何在javascript中执行不区分大小写的字符串比较?
最简单的方法(如果您不担心特殊的Unicode字符)是调用
1 | var areEqual = string1.toUpperCase() === string2.toUpperCase(); |
编辑:这个答案最初是9年前添加的。今天,您应该将
1 2 3 4 5 6 7 8 9 10 | 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')); |
或者,您可以使用
请注意,IE10或更低版本或某些移动浏览器不支持
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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
不区分大小写搜索
当要比较的两个字符串都是变量(不是常量)时,这会稍微复杂一点,因为需要从字符串生成regexp,但如果字符串中包含特殊的regex字符,则将字符串传递给regexp构造函数可能会导致不正确的匹配或失败的匹配。
如果你关心国际化,不要使用
http://www.i18nguy.com/unicode/turkish-i18n.html
借助正则表达式也可以实现。
1 | (/keyword/i).test(source) |
1 | (/keyword/).test(source) |
请记住,大小写是一个特定于区域的操作。根据具体情况,您可能需要考虑到这一点。例如,如果您正在比较两个人的姓名,您可能希望考虑区域设置,但如果您正在比较计算机生成的值(如UUID),则可能不会。这就是为什么我在utils库中使用以下函数(请注意,由于性能原因,不包括类型检查)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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; } |
正如在最近的评论中所说,
下面是一个简单的例子
1 | 'xyz'.localeCompare('XyZ', undefined, { sensitivity: 'base' }); // returns 0 |
以及可以使用的通用函数
1 2 3 | function equalsIgnoringCase(text, other) { text.localeCompare(other, undefined, { sensitivity: 'base' }) === 0; } |
请注意,您应该输入正在使用的特定区域设置,而不是
in Swedish, ? and a are separate base letters
灵敏度选项
浏览器支持截至发帖时,Android和Opera Mini的UC浏览器不支持区域设置和选项参数。请查看https://canius.com/search=localecompare以获取最新信息。
我最近创建了一个提供不区分大小写字符串帮助程序的微库:https://github.com/nickuraltsev/ignore-case。(内部使用
1 2 3 4 5 6 7 | 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 |
如果你关心不平等的方向(也许你想排序一个列表)您几乎必须进行大小写转换,因为Unicode中的小写字符比大写字母多,所以ToLowercase可能是要使用的最佳转换。
1 2 3 4 5 6 | function my_strcasecmp( a, b ) { if((a+'').toLowerCase() > (b+'').toLowerCase()) return 1 if((a+'').toLowerCase() < (b+'').toLowerCase()) return -1 return 0 } |
javascript似乎使用区域设置"c"进行字符串比较,因此结果排序将如果字符串包含的不是ASCII字母,则会很难看。如果不对弦进行更详细的检查,就无法完成很多工作。
假设我们想在字符串变量
考虑到第(1)和(2)点,示例如下:
1 2 3 4 5 6 7 | 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 } |
区分大小写比较有两种方法:
使用"search"字符串方法进行不区分大小写的搜索。阅读搜索和其他字符串方法:http://www.thesstech.com/pattern-matching-using-string-methods
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <!doctype html> <html> <head> // 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)); </head> </html> |
这里有很多答案,但我喜欢在扩展字符串库的基础上添加解决方案:
1 2 3 4 5 6 | String.prototype.equalIgnoreCase = function(str) { return (str != null && typeof str === 'string' && this.toUpperCase() === str.toUpperCase()); } |
这样你就可以像在爪哇一样使用它了!
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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"); } |
输出将是:
1 2 | "a == b" "b != c" |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | String.prototype.equalIgnoreCase = function(str) { return (str != null && typeof str === 'string' && this.toUpperCase() === str.toUpperCase()); } var a ="hello"; var b ="HeLLo"; var c ="world"; if (a.equalIgnoreCase(b)) { document.write("a == b"); document.write(""); } if (a.equalIgnoreCase(c)) { document.write("a == c"); } if (!b.equalIgnoreCase(c)) { document.write("b != c"); } |
1 2 3 4 | str = 'Lol', str2 = 'lOl', regex = new RegExp('^' + str + '$', 'i'); if (regex.test(str)) { console.log("true"); } |
不抛出异常和不使用慢速regex怎么样?
1 2 3 | return str1 != null && str2 != null && typeof str1 === 'string' && typeof str2 === 'string' && str1.toUpperCase() === str2.toUpperCase(); |
上面的代码段假定您不希望在字符串为空或未定义时匹配。
如果要匹配空/未定义,则:
1 2 3 4 | return (str1 == null && str2 == null) || (str1 != null && str2 != null && typeof str1 === 'string' && typeof str2 === 'string' && str1.toUpperCase() === str2.toUpperCase()); |
如果出于某种原因,您关心未定义vs空:
1 2 3 4 5 | return (str1 === undefined && str2 === undefined) || (str1 === null && str2 === null) || (str1 != null && str2 != null && typeof str1 === 'string' && typeof str2 === 'string' && str1.toUpperCase() === str2.toUpperCase()); |
使用regex进行字符串匹配或比较。
在javascript中,可以使用
例子:
1 2 3 4 5 6 7 | var matchString ="Test"; if (matchString.match(/test/i)) { alert('String matched'); } else { alert('String not matched'); } |
我写了一个分机。非常琐碎
1 2 3 4 5 | if (typeof String.prototype.isEqual!= 'function') { String.prototype.isEqual = function (str){ return this.toUpperCase()==str.toUpperCase(); }; } |
甚至这个问题也已经回答了。我有一个不同的方法来使用regexp和match来忽略区分大小写。请看我的链接https://jsfiddle.net/marchdave/7v8bd7dq/27/
1 2 3 4 5 6 7 8 9 10 11 12 | $("#btnGuess").click(guessWord); function guessWord() { var letter = $("#guessLetter").val(); var word = 'ABC'; var pattern = RegExp(letter, 'gi'); // pattern: /a/gi var result = word.match(pattern); alert('Ignore case sensitive:' + result); } |
由于没有答案清楚地提供了使用
1 2 3 4 5 | function compareInsensitive(str1, str2){ return typeof str1 === 'string' && typeof str2 === 'string' && new RegExp("^" + str1.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') +"$","i").test(str2); } |
它有几个优点:
如果两个字符串具有相同的已知区域设置,您可能希望使用这样的
1 2 3 | function equalIgnoreCase(s1: string, s2: string) { return new Intl.Collator("en-US", { sensitivity:"base" }).compare(s1, s2) === 0; } |
显然,为了提高效率,您可能需要缓存
这种方法的优点是,它应该比使用regexps快得多,并且基于一组非常可定制的现成的collator(参见上文中对
这是此答案的改进版本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | String.equal = function (s1, s2, ignoreCase, useLocale) { if (s1 == null || s2 == null) return false; if (!ignoreCase) { if (s1.length !== s2.length) return false; return s1 === s2; } if (useLocale) { if (useLocale.length) return s1.toLocaleLowerCase(useLocale) === s2.toLocaleLowerCase(useLocale) else return s1.toLocaleLowerCase() === s2.toLocaleLowerCase() } else { if (s1.length !== s2.length) return false; return s1.toLowerCase() === s2.toLowerCase(); } } |
< BR>
用途和测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | String.equal = function (s1, s2, ignoreCase, useLocale) { if (s1 == null || s2 == null) return false; if (!ignoreCase) { if (s1.length !== s2.length) return false; return s1 === s2; } if (useLocale) { if (useLocale.length) return s1.toLocaleLowerCase(useLocale) === s2.toLocaleLowerCase(useLocale) else return s1.toLocaleLowerCase() === s2.toLocaleLowerCase() } else { if (s1.length !== s2.length) return false; return s1.toLowerCase() === s2.toLowerCase(); } } // If you don't mind extending the prototype. String.prototype.equal = function(string2, ignoreCase, useLocale) { return String.equal(this.valueOf(), string2, ignoreCase, useLocale); } // ------------------ TESTS ---------------------- console.log("Tests..."); console.log('Case sensitive 1'); var result ="Abc123".equal("Abc123"); console.assert(result === true); console.log('Case sensitive 2'); result ="aBC123".equal("Abc123"); console.assert(result === false); console.log('Ignore case'); result ="AbC123".equal("aBc123", true); console.assert(result === true); console.log('Ignore case + Current locale'); result ="AbC123".equal("aBc123", true); console.assert(result === true); console.log('Turkish test 1 (ignore case, en-US)'); result ="IiiI".equal("?i?I", true,"en-US"); console.assert(result === false); console.log('Turkish test 2 (ignore case, tr-TR)'); result ="IiiI".equal("?i?I", true,"tr-TR"); console.assert(result === true); console.log('Turkish test 3 (case sensitive, tr-TR)'); result ="IiiI".equal("?i?I", false,"tr-TR"); console.assert(result === false); console.log('null-test-1'); result ="AAA".equal(null); console.assert(result === false); console.log('null-test-2'); result = String.equal(null,"BBB"); console.assert(result === false); console.log('null-test-3'); result = String.equal(null, null); console.assert(result === false); |