JavaScriptで文字列に部分文字列の配列のテキストが含まれているかどうかを確認するにはどうすればよいですか?


163

かなり簡単です。JavaScriptでは、文字列が配列に保持されている部分文字列を含んでいるかどうかを確認する必要があります。


map()新しいHTML5-JavaScriptバージョンには関数はありませんか?そのトピックについて何か読んだことを覚えています...
マーティンヘニングス

@マーティン:良い点ではmapなく、somesome役立つでしょうが、関数を渡す必要があります。
TJクラウダー、2011

回答:


224

それを行う組み込みのものは何もありません。そのための関数を作成する必要があります。

文字列に正規表現で特別な文字が含まれていないことがわかっている場合は、次のように少しカンニングできます。

if (new RegExp(substrings.join("|")).test(string)) {
    // At least one match
}

...これは、探している部分文字列(たとえば)の一連の代替である正規表現を作成し、one|twoそれらのいずれかに一致するかどうかをテストしますが、いずれかの部分文字列に特殊な文字が含まれているかどうかをテストします正規表現(で*[など)には、最初にそれらをエスケープする必要があるだろうと、あなたはより良いオフだけではなく、退屈なループをやっています。

実例:


質問へのコメントで、マーティンArray.prototype.mapECMAScript5の新しいメソッドについて尋ねます。mapそれはそれほど多くの助けではありませんが、someです:

if (substrings.some(function(v) { return str.indexOf(v) >= 0; })) {
    // There's at least one
}

実例:

ECMAScript5準拠の実装でのみ使用できますが、ポリフィルは簡単です。


2020年の更新:このsome例は、矢印関数(ES2015 +)を使用するincludesとより簡単になる可能性がありますindexOf

if (substrings.some(v => str.includes(v))) {
    // There's at least one
}

実例:

または、それを投げるbindだけですが、私にとっては、矢印関数ははるかに読みやすくなっています。

if (substrings.some(str.includes.bind(str))) {
    // There's at least one
}

実例:


2
「気をつけてください、それはある程度のオーバーヘッドを意味します...」 しかし、気にすることは何もありません
TJクラウダー2013年

'|'を除くすべての正規表現文字を削除することで、上記のソリューションを拡張できますnew RegExp(substrings.join("|").replace(/[^\w\s^|]/gi, '')).test(string)
user007

indexOfの使用はあいまいすぎて、奇妙な結果をもたらす可能性があります。等号演算子を使用して、文字列と一致するように単純に配置できます。例えば('disconnect'.indexOf('connect') >= 0) === trueしかし('disconnect' === 'conenct') === false
kylewelsby

@halfcube:えっ?私はあなたを理解していません、恐れています。上記の答えには、それ'disconnect' === 'connect'が何か以外のことを示唆するものはありませんfalse。また、indexOfあいまいではなく、非常に明確に定義されています。
TJクラウダー2015年

indexOf両方にマッチしますdisconnectし、connectどこが経験してきた場合には、これらは、私は条件付きでの結果を返すようにしたい二つの異なる場合があります。
kylewelsby

54
var yourstring = 'tasty food'; // the string to check against


var substrings = ['foo','bar'],
    length = substrings.length;
while(length--) {
   if (yourstring.indexOf(substrings[length])!=-1) {
       // one of the substrings is in yourstring
   }
}

50

ワンラインソリューション

substringsArray.some(substring=>yourBigString.includes(substring))

true\false部分文字列の場合に返しますexists\does'nt exist

ES6サポートが必要


矢印関数を使用した
優れた

7
あなたは子供です...私が子供の頃、私たちは「for」ループと呼ばれるこれらのものを使用しなければなりませんでした、そしてあなたは複数の行を使用し、配列が1または0ベースであるかどうかを知っていました、ええ...あなたが得た時間の半分それは間違っていて、デバッグして 'i'と呼ばれる小さなバグを探していました。
aamarks

25
function containsAny(str, substrings) {
    for (var i = 0; i != substrings.length; i++) {
       var substring = substrings[i];
       if (str.indexOf(substring) != - 1) {
         return substring;
       }
    }
    return null; 
}

var result = containsAny("defg", ["ab", "cd", "ef"]);
console.log("String was found in substring " + result);

1
一番わかりやすい!
ダリルH

さらに、文字列内の最初の単語の出現を返すため、非常に役立ちます。真/偽だけではありません。
カイノアック

20

グーグルする人のために、

確かな答えがあるはずです。

const substrings = ['connect', 'ready'];
const str = 'disconnect';
if (substrings.some(v => str === v)) {
   // Will only return when the `str` is included in the `substrings`
}

2
以下:if(substrings.some(v => v === str)){
kofifus

10
これは、文字列に部分文字列の配列からのテキストが含まれているかどうかを尋ねるわずかに異なる質問への回答であることに注意してください。このコードは、文字列部分文字列の1つであるかどうかをチェックします。「含む」が何を意味するかによると思います。
fcrick

8
var str = "texttexttext";
var arr = ["asd", "ghj", "xtte"];
for (var i = 0, len = arr.length; i < len; ++i) {
    if (str.indexOf(arr[i]) != -1) {
        // str contains arr[i]
    }
}

編集:テストの順序が重要でない場合は、これを使用できます(ループ変数を1つだけ使用)。

var str = "texttexttext";
var arr = ["asd", "ghj", "xtte"];
for (var i = arr.length - 1; i >= 0; --i) {
    if (str.indexOf(arr[i]) != -1) {
        // str contains arr[i]
    }
}

最初の例ではlen変数は必要ありませんi < arr.length。チェックするだけです。
GreySage

3

配列が大きくない場合は、ループを使用して、を使用して文字列を各部分文字列に対して個別にチェックできますindexOf()。または、部分文字列を代替として正規表現を作成することもできます。


100個の部分文字列のリストがあるとします。RegExpまたはループのどちらがより効率的ですか。
Diyorbek Sadullayev

3

検索文字列または検索文字列の配列を使用してタグまたはキーワードの配列を検索するJavaScript関数。(ES5の いくつかの配列メソッドとES6の 矢印関数を使用

// returns true for 1 or more matches, where 'a' is an array and 'b' is a search string or an array of multiple search strings
function contains(a, b) {
    // array matches
    if (Array.isArray(b)) {
        return b.some(x => a.indexOf(x) > -1);
    }
    // string match
    return a.indexOf(b) > -1;
}

使用例:

var a = ["a","b","c","d","e"];
var b = ["a","b"];
if ( contains(a, b) ) {
    // 1 or more matches found
}

2

私があなたがStringプロトタイプを拡張/変更することを提案しているわけではありませんが、これは私がやったことです:

String.prototype.includes()

String.prototype.includes = function (includes) {
    console.warn("String.prototype.includes() has been modified.");
    return function (searchString, position) {
        if (searchString instanceof Array) {
            for (var i = 0; i < searchString.length; i++) {
                if (includes.call(this, searchString[i], position)) {
                    return true;
                }
            }
            return false;
        } else {
            return includes.call(this, searchString, position);
        }
    }
}(String.prototype.includes);

console.log('"Hello, World!".includes("foo");',          "Hello, World!".includes("foo")           ); // false
console.log('"Hello, World!".includes(",");',            "Hello, World!".includes(",")             ); // true
console.log('"Hello, World!".includes(["foo", ","])',    "Hello, World!".includes(["foo", ","])    ); // true
console.log('"Hello, World!".includes(["foo", ","], 6)', "Hello, World!".includes(["foo", ","], 6) ); // false


2

TJクロウダーのソリューションから、この問題に対処するためのプロトタイプを作成しました。

Array.prototype.check = function (s) {
  return this.some((v) => {
    return s.indexOf(v) >= 0;
  });
};

2
substringsArray.every(substring=>yourBigString.indexOf(substring) === -1)

完全なサポートのために;)


2

ベストアンサーはこちらです:これも大文字と小文字を区別しません

    var specsFilter = [.....];
    var yourString = "......";

    //if found a match
    if (specsFilter.some((element) => { return new RegExp(element, "ig").test(yourString) })) {
        // do something
    }

1

underscore.jsまたはlodash.jsを使用すると、文字列の配列に対して以下を実行できます。

var contacts = ['Billy Bob', 'John', 'Bill', 'Sarah'];

var filters = ['Bill', 'Sarah'];

contacts = _.filter(contacts, function(contact) {
    return _.every(filters, function(filter) { return (contact.indexOf(filter) === -1); });
});

// ['John']

そして単一の文字列で:

var contact = 'Billy';
var filters = ['Bill', 'Sarah'];

_.every(filters, function(filter) { return (contact.indexOf(filter) >= 0); });

// true

1

これは非常に遅いですが、私はこの問題に遭遇しました。自分のプロジェクトでは、文字列が配列内にあるかどうかを確認するために以下を使用しました。

["a","b"].includes('a')     // true
["a","b"].includes('b')     // true
["a","b"].includes('c')     // false

このようにして、事前定義された配列を取得して、文字列が含まれているかどうかを確認できます。

var parameters = ['a','b']
parameters.includes('a')    // true

1

TJクロウダーの答えに基づいて構築

エスケープされたRegExpを使用して、少なくとも1つのサブストリングの「少なくとも1回」の出現をテストします。

function buildSearch(substrings) {
  return new RegExp(
    substrings
    .map(function (s) {return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');})
    .join('{1,}|') + '{1,}'
  );
}


var pattern = buildSearch(['hello','world']);

console.log(pattern.test('hello there'));
console.log(pattern.test('what a wonderful world'));
console.log(pattern.test('my name is ...'));


1

スペースまたはその他の一般的な文字で区切られた完全な「単語」で構成される部分文字列の長いリストを使用している場合は、検索を少し賢くすることができます。

最初に文字列をXのグループ、次にX + 1、次にX + 2、...、Yまでに分割します。XとYは、サブストリング内の単語数が最も少ない単語と最も多い単語の数です。たとえば、Xが1でYが4の場合、「アルファベータガンマデルタ」は次のようになります。

「アルファ」「ベータ」「ガンマ」「デルタ」

「アルファベータ」「ベータガンマ」「ガンマデルタ」

「アルファベータガンマ」「ベータガンマデルタ」

「アルファベータガンマデルタ」

Xが2でYが3の場合、最初と最後の行を省略します。

このリストをセット(またはマップ)に挿入すると、文字列比較よりもはるかに高速に、このリストをすばやく検索できます。

欠点は、「ta Gamm」のような部分文字列を検索できないことです。もちろん、単語ごとではなく文字ごとに分割することでそれを可能にすることもできますが、その場合は大規模なセットを作成する必要があり、そのために費やした時間/メモリがメリットを上回ります。



0

次のように確認できます:

<!DOCTYPE html>
<html>
   <head>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
      <script>
         $(document).ready(function(){
         var list = ["bad", "words", "include"] 
         var sentence = $("#comments_text").val()

         $.each(list, function( index, value ) {
           if (sentence.indexOf(value) > -1) {
                console.log(value)
            }
         });
         });
      </script>
   </head>
   <body>
      <input id="comments_text" value="This is a bad, with include test"> 
   </body>
</html>

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