大文字と小文字を区別しない文字列比較を行う方法は?


1056

JavaScriptで大文字と小文字を区別しない文字列比較を実行するにはどうすればよいですか?


25
新しく追加された.localeCompare()javascriptメソッドを参照してください。執筆時(IE11 +)は、最新のブラウザでのみサポートされています。developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…を
Adrien Be


5
@AdrienBe "A".localeCompare( "a" );1Chrome 48コンソールに戻ります。
Manuell

3
@manuell "a""A"、ソート時に前に来ることを意味します。同様に"a"前に来ます"b"。この動作が望ましくない場合は、.toLowerCase()各文字/文字列にしたい場合があります。すなわち。developer.mozilla.org/en/docs/Web/JavaScript/Reference/…を"A".toLowerCase().localeCompare( "a".toLowerCase() )参照して
Adrien Be

2
比較は、文字列の並べ替え/並べ替えに使用される用語なので、ずっと前にここでコメントしました。===等しいかどうかをチェックしますが、文字列の並べ替え/並べ替えには不十分です(最初にリンクした質問を参照してください)。
Adrien Be

回答:


1163

これを行う最も簡単な方法(特別なUnicode文字について心配していない場合)は、次のように呼び出しますtoUpperCase

var areEqual = string1.toUpperCase() === string2.toUpperCase();

44
大文字または小文字への変換は、すべての言語で大文字と小文字を区別しない正しい比較を提供します。 i18nguy.com/unicode/turkish-i18n.html
サミュエルネフ

57
@sam:わかった。それが私が書いif you're not worried about special Unicode charactersた理由です。
10

141
好む理由があるtoUpperCase以上はtoLowerCase
jpmc26 2014年


19
これは本当にJSが提供する最高のものですか?
クーゲル2017年

210

編集:この回答は最初に9年前に追加されました。今日localeCompareは、次のsensitivity: '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'));

{ sensitivity: 'accent' }告げるlocaleCompare()と同じと同じ基本文字の二つの変種を治療することがない限り、それらは、上記(第3の例のように)異なるアクセントを持っています。

代わりに、を使用できます{ sensitivity: 'base' }。これにより、2つの文字が同じである限り、それらの文字は同等として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  */;
}

元の答え

JavaScriptで大文字と小文字を区別しない比較を行う最良のmatch()方法は、iフラグを指定してRegExp メソッドを使用することです。

大文字と小文字を区別しない検索

比較される両方の文字列が変数(定数ではない)である場合、文字列からRegExpを生成する必要がありますが、文字列をRegExpコンストラクターに渡すと、文字列に特別な正規表現がある場合、一致が正しくなかったり、一致が失敗したりする可能性がありますその中の文字。

国際化に関心がある場合は使用しないtoLowerCase()toUpperCase()、すべての言語で大文字と小文字を区別しない正確な比較を提供しないようにしてください。

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


5
@Quandary、はい、それは私が処理しなければならなかったと述べたものです-「文字列からRegExpを生成する必要がありますが、文字列をRegExpコンストラクタに渡すと、文字列に特別な正規表現文字が含まれていると、一致が正しくなかったり、一致が失敗したりする可能性があります」
サミュエルネフ

21
これを使用することは、大文字と小文字を区別しない文字列比較の最もコストのかかるソリューションです。RegExpは複雑なパターンマッチングのためのものです。そのため、パターンごとに決定木を作成し、それを入力文字列に対して実行する必要があります。うまくいくかもしれませんが、ジェット飛行機で次のブロックに買い物に行くのと同じです。tl; dr:これを行わないでください。
Agoston Horvath 2015

2
localeCompare()を使用することもできますが、'a'.localeCompare('A')大文字と小文字を区別しない文字列比較で探しているopと同じように-1を返します。
StingyJack 2018年

3
@StingyJackは、localeCompareを使用して大文字と小文字を区別しない比較を行います。'a'.localeCompare( 'A'、undefined、{Sensitivity: 'base'})
Judah Gabriel Himango

1
注:このlocaleCompareバージョンでは、JavaScriptエンジンがECMAScript®国際化APIをサポートしている必要がありますが必須ではありません。そのため、これに依存する前に、使用している環境で動作することを確認することをお勧めします。たとえば:const compareInsensitive = "x".localeCompare("X", undefined, {sensitivity: "base"}) === 0 ? (a, b) => a.localeCompare(b, undefined, {sensitivity: "base"}) : (a, b) => a.toLowerCase().localeCompare(b.toLowerCase());またはそのようなもの。
TJクラウダー

46

最近のコメントで述べたように、string::localeCompare(他の強力なものの中でも)大文字と小文字を区別しない比較をサポートします。

ここに簡単な例があります

'xyz'.localeCompare('XyZ', undefined, { sensitivity: 'base' }); // returns 0

そして、あなたが使用できる一般的な関数

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

代わりに、undefined作業している特定のロケールを入力する必要があることに注意してください。これはMDNドキュメントに示されているように重要です

スウェーデン語では、äとaは別々の基本文字です

感度オプション

MDNから表にした感度オプション

ブラウザのサポート

投稿の時点では、Android向けのUCブラウザーとOpera Mini ロケールオプションのパラメーターをサポートしていません。最新情報については、https://caniuse.com/#search=localeCompareを確認してください


35

正規表現の助けを借りて、私たちも達成できます。

(/keyword/i).test(source)

/i大文字小文字を区別しないためです。必要でない場合は、大文字と小文字を区別しない一致を無視してテストできます

(/keyword/).test(source)

17
このような正規表現を使用すると、部分文字列に一致します。あなたの例では、文字列keyWORDはインデッドとなり、ポジティブな一致になります。しかし、文字列this is a keyword yoor keywordsも肯定的な一致になります。それに注意してください:-)
Elmer

6
これは、質問で尋ねられたように、等価チェック(大文字と小文字を区別しない)には答えません!しかし、これはContainsチェックです!使用しないでください
S.Serpooshan

4
もちろん、文字列全体と一致させるには、正規表現をに変更できます/^keyword$/.test(source)が、1)keywordが定数でない場合は、行う必要がありますnew RegExp('^' + x + '$').test(source)。2)正規表現を使用して、大文字と小文字を区別しない文字列の同等性をテストするだけです。まったく効率的ではありません。
JHH

28

大文字小文字の区別はロケール固有の操作であることを覚えておいてください。シナリオによっては、それを考慮に入れたい場合があります。たとえば、2人の名前を比較する場合はロケールを検討する必要がありますが、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;
}

「!!」を使う理由はありますか?if句が値の真実性を評価するのを許可する代わりに、明示的なブール変換を実行するには?
Celos 2014年

必須ではありません。他のバージョンのより複雑なコードからそれを得たと思います。答えを更新しました。
Shital Shah 2014

@thekodester関数にバグがあります。これcompareStrings("", "")false文字列が等しいという事実にもかかわらず与えます。
セルゲイ

@Sergeyそれはtrue私のために戻ってきます。おそらくそれはあなたのブラウザのバグですか?
ジェナスローン

14

私は最近、大文字と小文字を区別しない文字列ヘルパーを提供するマイクロライブラリを作成しました: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

12

不等式の方向が気になる場合(おそらくリストをソートしたい場合)、大文字と小文字の変換を行う必要があります。Unicodeの小文字のほうが大文字のtoLowerCaseよりも多いので、おそらく使用するのに最適な変換です。

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

JavaScriptは文字列の比較にロケール「C」を使用しているようです。そのため、文字列にASCII文字以外の文字が含まれている場合、結果の順序は醜くなります。文字列をより詳細に検査しなければ、それについてできることは多くありません。


7

文字列変数needleで文字列変数を検索するとしますhaystack。3つの落とし穴があります。

  1. 国際化されたアプリケーションは、string.toUpperCaseとを回避する必要がありstring.toLowerCaseます。代わりに大文字小文字を無視する正規表現を使用してください。たとえば、var needleRegExp = new RegExp(needle, "i");その後にが続きneedleRegExp.test(haystack)ます。
  2. 一般に、の値がわからない場合がありますneedleneedle正規表現の特殊文字が含まれていないことに注意してください。を使用してこれらをエスケープしneedle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");ます。
  3. 他のケースで、大文字と小文字を無視して正確にneedleandと一致させたい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
}

賭けます!必要なのは、new RegExp(...)3行目のパーツを次のように置き換えることだけですnew RegExp("^" + needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") + "$", "i");。これにより、検索文字列の前後に他の文字がないことを確認できますneedle
クリスシュート2016

4

大文字と小文字を区別しない比較には2つの方法があります。

  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>

4

ここにはたくさんの答えがありますが、私は文字列libの拡張に基づいて解決策を追加したいと思います。

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) {
  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("<br>");
}
if (a.equalIgnoreCase(c)) {
  document.write("a == c");
}
if (!b.equalIgnoreCase(c)) {
  document.write("b != c");
}


4

文字列の一致または比較にはRegExを使用します。

JavaScriptでは、match()文字列の比較に使用できます。i。RegExを含めるでください。

例:

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

1
部分一致で問題がないことを確認しますmatchString.match(/^test$/i)。それ以外の場合は、
hackel

小文字の「テスト」の代わりにあなたはvar x = 'test'を持っています、うまくいきますmatchString.match(/x/i)か?そうでない場合、何が機能しますか?
Razvan Zamfir

3
str = 'Lol', str2 = 'lOl', regex = new RegExp('^' + str + '$', 'i');
if (regex.test(str)) {
    console.log("true");
}

3

両方の文字列が同じ既知のロケールのものである場合は、次のIntl.Collatorようなオブジェクトを使用できます。

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

明らかに、Collatorより良い効率のためにキャッシュしたいかもしれません。

このアプローチの利点は、それがはるかに高速に正規表現を使用するよりもすべきであり、(の説明を参照極めてカスタマイズに基づいていることであるlocalesoptionsすぐに使用できる丁合の上記の記事では、コンストラクタのパラメータ)を設定します。


感度のもう1つのオプションはでaccent、大文字と小文字を区別しませんが、aáを別々の文字として扱います。だから、baseまたはaccent両方の正確なニーズに応じて、適切であろう。
Matthew Crumley、

2

拡張機能を書きました。非常に些細な

if (typeof String.prototype.isEqual!= 'function') {
    String.prototype.isEqual = function (str){
        return this.toUpperCase()==str.toUpperCase();
     };
}

1
String#isEqualの動作方法が異なる2つのコードベースが同時に存在しようとするとどうなりますか?
Ryan Cavanaugh、

3
@KhanSharp多くの人々は、組み込み型のプロトタイプを変更することをアンチパターンと見なしています。これが、人々があなたの答えに反対投票する理由です。
jt000 14

1
未知のメソッド定義を好むのは悪い考えではありませんか?たとえば、一部のブラウザがすべてのページを実装するString#isEqualObject#isEqualネイティブに実装するかを決定するとすぐに、仕様が正確に一致しない場合は奇妙な動作をする可能性があります。
Robert

2

この質問でさえすでに答えています。RegExpとmatchを使用して大文字と小文字を区別する別のアプローチがあります。私のリンク https://jsfiddle.net/marchdave/7v8bd7dq/27/をご覧ください

$("#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

例外をスローせず、遅い正規表現を使用しないのはどうですか?

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

上記のスニペットは、いずれかの文字列がnullまたは未定義の場合は一致させないことを前提としています。

null /未定義に一致させる場合は、次のようにします。

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

なんらかの理由で未定義とnullを気にかけている場合:

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

あるいは単にstr1 == str2 || ...
16年

1

答えが明確にを使用するための簡単なコードスニペットを提供していないので、これがRegExp私の試みです:

function compareInsensitive(str1, str2){ 
  return typeof str1 === 'string' && 
    typeof str2 === 'string' && 
    new RegExp("^" + str1.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + "$", "i").test(str2);
}

これにはいくつかの利点があります。

  1. パラメータタイプを検証します(undefinedたとえば、文字列以外のパラメータは、次のような式をクラッシュさせますstr1.toUpperCase())。
  2. 可能な国際化の問題に悩まされていません。
  3. RegExp文字列をエスケープします。

しかし、脱出する正規表現の欠如に苦しんでいます。
Qwertiy 2017

@Qwertiyフェアポイント、stackoverflow.com / a / 3561711/67824ごとにエスケープを追加。
Ohad Schneider

0

これは、この回答の改良版です。

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();
    }
}



使用法とテスト:


0

両方をより低い値に変換し(パフォーマンス上の理由から1回のみ)、それらを1行で三項演算子と比較します。

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

Cは死んだと誰が言うのですか?:D
Seth

0

asciiテキストを扱っていることがわかっている場合は、大文字と小文字の文字オフセット比較を使用できます。

「完全な」文字列(照合したい文字列)が小文字であることを確認してください:

const CHARS_IN_BETWEEN = 32;
const LAST_UPPERCASE_CHAR = 90; // Z
function strMatchesIgnoreCase(lowercaseMatch, value) {
    let i = 0, matches = lowercaseMatch.length === value.length;
    while (matches && i < lowercaseMatch.length) {
        const a = lowercaseMatch.charCodeAt(i);
        const A = a - CHARS_IN_BETWEEN;
        const b = value.charCodeAt(i);
        const B = b + ((b > LAST_UPPERCASE_CHAR) ? -CHARS_IN_BETWEEN : CHARS_IN_BETWEEN);
        matches = a === b // lowerA === b
            || A === b // upperA == b
            || a === B // lowerA == ~b
            || A === B; // upperA == ~b
        i++;
    }
    return matches;
}

0

私はこの簡単な省略形が好きです-

export const equalsIgnoreCase = (str1, str2) => {
    return (!str1 && !str2) || (str1 && str2 && str1.toUpperCase() == str2.toUpperCase())
}

処理が速く、意図したとおりに実行されます。


0

この javascriptライブラリは多くの文字列操作を提供しているようです。とても便利です

インストールする方法

npm install --save string

インポート

var S = require('string');

比較文字列を無視

var isEqual = S('ignoreCase').equalsIgnoreCase('IGNORECASE')
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.