Bagaimana cara memeriksa apakah string berisi teks dari array substring dalam JavaScript?

163

Cukup lurus ke depan. Dalam javascript, saya perlu memeriksa apakah string berisi substring yang disimpan dalam array.

PercivalMcGullicuddy
sumber
Apakah tidak ada map()fungsi dalam versi HTML5-JavaScript baru? Saya ingat pernah membaca sesuatu tentang topik itu ...
Martin Hennings
@ Martin: Poin bagus, tidak mapsebanyak itu some. someakan membantu, tetapi Anda harus melewatinya fungsi.
TJ Crowder

Jawaban:

224

Tidak ada built-in yang akan melakukan itu untuk Anda, Anda harus menulis fungsi untuk itu.

Jika Anda tahu string tidak mengandung karakter apa pun yang khusus dalam ekspresi reguler, maka Anda dapat sedikit curang, seperti ini:

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

... yang membuat ekspresi reguler yang merupakan serangkaian pergantian untuk substring yang Anda cari (misalnya, one|two) dan tes untuk melihat apakah ada kecocokan untuk salah satu dari mereka, tetapi jika salah satu substring berisi karakter yang spesial di regexes ( *,, [dll.), Anda harus melarikan diri terlebih dahulu dan Anda lebih baik melakukan loop membosankan saja.

Contoh Langsung:


Dalam komentar pada pertanyaan, Martin bertanya tentang Array.prototype.mapmetode baru di ECMAScript5. maptidak banyak membantu, tetapi some:

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

Contoh Langsung:

Anda hanya memilikinya pada implementasi ECMAScript5-compliant, meskipun sepele untuk polyfill.


Pembaruan pada tahun 2020 : someContohnya bisa lebih sederhana dengan fungsi panah (ES2015 +), dan Anda mungkin menggunakan includesdaripada indexOf:

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

Contoh Langsung:

Atau bahkan melemparkannya bind, meskipun bagi saya fungsi panah jauh lebih mudah dibaca:

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

Contoh Langsung:

TJ Crowder
sumber
2
"Pikiran kamu, itu berarti beberapa overhead ..." tapi tidak ada yang peduli .
TJ Crowder
Anda dapat memperpanjang atas solusi dengan menghapus semua karakter regex kecuali '|': new RegExp(substrings.join("|").replace(/[^\w\s^|]/gi, '')).test(string).
user007
penggunaan indexOf bisa terlalu kabur dan menghasilkan hasil yang aneh. Ini bisa dengan mudah dicocokkan dengan string menggunakan operator equal. mis. ('disconnect'.indexOf('connect') >= 0) === truetapi('disconnect' === 'conenct') === false
kylewelsby
@halfcube: Hah? Saya tidak mengerti Anda, saya takut. Tidak ada dalam jawaban di atas yang menunjukkan bahwa 'disconnect' === 'connect'tidak ada yang lain selain itu false. Juga, indexOftidak kabur, itu memang sangat jelas didefinisikan.
TJ Crowder
indexOfakan cocok dengan keduanya disconnectdan connectdi mana dalam kasus yang saya alami, ini adalah dua kasus yang berbeda yang saya ingin hasil untuk dalam kondisi bersyarat.
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
   }
}
gua
sumber
50

Solusi satu baris

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

Kembali true\falsejika substringexists\does'nt exist

Membutuhkan dukungan ES6

Praveena
sumber
Solusi hebat menggunakan fungsi panah
GuerillaRadio
7
Kalian anak-anak ... dulu ketika saya masih kecil kami harus menggunakan hal-hal ini yang disebut 'untuk' loop, dan Anda harus menggunakan beberapa baris dan tahu apakah array Anda berbasis 1 atau nol, ya ... setengah dari waktu yang Anda dapatkan salah dan harus men-debug dan mencari bugger kecil yang disebut '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);
Jim Blackler
sumber
1
yang termudah untuk dipahami!
Daryl H
Plus itu mengembalikan kemunculan pertama kata dalam string, yang sangat membantu. Bukan hanya benar / salah.
Kai Noack
20

Untuk orang-orang Googling,

Jawaban yang solid seharusnya.

const substrings = ['connect', 'ready'];
const str = 'disconnect';
if (substrings.some(v => str === v)) {
   // Will only return when the `str` is included in the `substrings`
}
Kylewelsby
sumber
2
atau lebih pendek: if (substrings.some (v => v === str)) {
kofifus
10
Perhatikan bahwa ini adalah jawaban untuk pertanyaan yang sedikit berbeda, yang menanyakan apakah string berisi teks dari berbagai substring. Kode ini memeriksa apakah string adalah salah satu dari substring. Tergantung pada apa yang dimaksud dengan "mengandung" kurasa.
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]
    }
}

sunting: Jika urutan tes tidak masalah, Anda dapat menggunakan ini (hanya dengan satu variabel loop):

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]
    }
}
pengguna
sumber
Contoh pertama Anda tidak perlu lenvariabel, cukup periksa i < arr.length.
GreySage
3

Jika array tidak besar, Anda bisa mengulang dan memeriksa string terhadap setiap substring secara individual indexOf(). Atau Anda dapat membuat ekspresi reguler dengan substring sebagai alternatif, yang mungkin atau mungkin tidak lebih efisien.

Gintautas Miliauskas
sumber
Katakanlah kita memiliki daftar 100 substring. Cara mana yang lebih efisien: RegExp atau loop?
Diyorbek Sadullayev
3

Fungsi Javascript untuk mencari array tag atau kata kunci menggunakan string pencarian atau array string pencarian. (Menggunakan ES5 beberapa metode array dan fungsi panah 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;
}

Contoh penggunaan:

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

Bukannya saya menyarankan Anda pergi dan memperluas / memodifikasi Stringprototipe, tapi inilah yang saya lakukan:

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

akinuri
sumber
2

Menggambar dari solusi TJ Crowder, saya membuat prototipe untuk mengatasi masalah ini:

Array.prototype.check = function (s) {
  return this.some((v) => {
    return s.indexOf(v) >= 0;
  });
};
alavry
sumber
2
substringsArray.every(substring=>yourBigString.indexOf(substring) === -1)

Untuk dukungan penuh;)

ricca
sumber
2

Jawaban terbaik ada di sini: Ini juga case-sensitive

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

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

Menggunakan underscore.js atau lodash.js, Anda bisa melakukan hal berikut pada array string:

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']

Dan pada satu string:

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

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

// true
BuffMcBigHuge
sumber
1

Ini sangat terlambat, tapi saya baru saja mengalami masalah ini. Dalam proyek saya sendiri, saya menggunakan yang berikut ini untuk memeriksa apakah sebuah string berada dalam array:

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

Dengan cara ini Anda dapat mengambil array yang telah ditentukan dan memeriksa apakah itu berisi string:

var parameters = ['a','b']
parameters.includes('a')    // true
Lincoln Anders
sumber
1

membangun jawaban TJ Crowder

menggunakan escaped RegExp untuk menguji kemunculan "setidaknya satu kali", dari setidaknya salah satu substring.

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 ...'));

DhavalW
sumber
1

Jika Anda bekerja dengan daftar panjang substring yang terdiri dari "kata" penuh yang dipisahkan oleh spasi atau karakter umum lainnya, Anda bisa menjadi sedikit pintar dalam pencarian Anda.

Pertama-tama bagi string Anda menjadi kelompok-kelompok X, lalu X + 1, lalu X + 2, ..., hingga Y. X dan Y harus menjadi jumlah kata dalam substring Anda dengan kata yang paling sedikit dan paling banyak. Misalnya jika X adalah 1 dan Y adalah 4, "Alpha Beta Gamma Delta" menjadi:

"Alpha" "Beta" "Gamma" "Delta"

"Alpha Beta" "Beta Gamma" "Gamma Delta"

"Alpha Beta Gamma" "Beta Gamma Delta"

"Alpha Beta Gamma Delta"

Jika X akan menjadi 2 dan Y menjadi 3, maka Anda akan menghilangkan baris pertama dan terakhir.

Sekarang Anda dapat mencari di daftar ini dengan cepat jika Anda memasukkannya ke dalam Set (atau Peta), jauh lebih cepat daripada dengan perbandingan string.

Kekurangannya adalah Anda tidak dapat mencari substring seperti "ta Gamm". Tentu saja Anda bisa membiarkannya dengan memecah berdasarkan karakter alih-alih dengan kata, tetapi kemudian Anda harus sering membangun Set yang besar dan waktu / memori yang dihabiskan untuk melakukannya melebihi manfaatnya.

Emil Norén
sumber
1

Untuk dukungan penuh (tambahan untuk @ricca 's verions ).

wordsArray = ['hello', 'to', 'nice', 'day']
yourString = 'Hello. Today is a nice day'.toLowerCase()
result = wordsArray.every(w => yourString.includes(w))
console.log('result:', result)

TitanFighter
sumber
0

Anda dapat memeriksa seperti ini:

<!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>
Dhaval Soni
sumber
-1
let obj = [{name : 'amit'},{name : 'arti'},{name : 'sumit'}];
let input = 'it';

Gunakan filter:

obj.filter((n)=> n.name.trim().toLowerCase().includes(input.trim().toLowerCase()))
ArtiSK
sumber
silakan kunjungi dan periksa bagaimana menjawab pertanyaan .
Yunus Temurlenk
@YunusTemurlenk thnx
ArtiSK