Wie überprüfe ich, ob eine Zeichenfolge Text aus einem Array von Teilzeichenfolgen in JavaScript enthält?


163

Ziemlich einfach. In Javascript muss ich überprüfen, ob eine Zeichenfolge Teilzeichenfolgen enthält, die in einem Array enthalten sind.


Gibt es map()in der neuen HTML5-JavaScript-Version keine Funktion? Ich erinnere mich, dass ich etwas zu diesem Thema gelesen habe ...
Martin Hennings

@ Martin: Guter Punkt, nicht mapso viel wie some. somewürde helfen, aber du müsstest ihm eine Funktion übergeben.
TJ Crowder

Antworten:


222

Es gibt nichts Eingebautes, das das für Sie erledigt. Sie müssen eine Funktion dafür schreiben.

Wenn Sie wissen, dass die Zeichenfolgen keine der Zeichen enthalten, die in regulären Ausdrücken besonders sind, können Sie ein bisschen schummeln, wie folgt:

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

... wodurch ein regulärer Ausdruck erstellt wird, der eine Reihe von Abwechslungen für die gesuchten Teilzeichenfolgen (z. B. one|two) darstellt und prüft, ob Übereinstimmungen für eine der Teilzeichenfolgen vorhanden sind, ob jedoch eine der Teilzeichenfolgen spezielle Zeichen enthält in regulären Ausdrücke ( *, [usw.), dann würden Sie sie zuerst entkommen müssen und du bist besser dran , nur die langweilige Schleife stattdessen tun.

Live-Beispiel:


In einem Kommentar zur Frage fragt Martin nach der neuen Array.prototype.mapMethode in ECMAScript5. mapist nicht allzu viel Hilfe, aber es someist:

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

Live-Beispiel:

Sie haben es nur in ECMAScript5-kompatiblen Implementierungen, obwohl es für Polyfill trivial ist.


Update im Jahr 2020 : Das someBeispiel kann mit einer Pfeilfunktion (ES2015 +) einfacher sein, und Sie verwenden möglicherweise includeseher als indexOf:

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

Live-Beispiel:

Oder sogar darauf werfen bind, obwohl für mich die Pfeilfunktion viel besser lesbar ist:

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

Live-Beispiel:


2
"Wohlgemerkt, es bedeutet etwas Overhead ...", aber nichts, worüber man sich Sorgen machen müsste .
TJ Crowder

Sie können die obige Lösung erweitern, indem Sie alle Regex-Zeichen mit Ausnahme des '|' entfernen : new RegExp(substrings.join("|").replace(/[^\w\s^|]/gi, '')).test(string).
user007

Die Verwendung von indexOf kann zu unscharf sein und zu einem merkwürdigen Ergebnis führen. Es kann einfach so platziert werden, dass es mit dem Operator des Gleichen mit der Zeichenfolge übereinstimmt. zB ('disconnect'.indexOf('connect') >= 0) === trueaber('disconnect' === 'conenct') === false
kylewelsby

@halfcube: Huh? Ich verstehe dich nicht, fürchte ich. Nichts in der obigen Antwort deutet darauf hin, dass 'disconnect' === 'connect'dies alles andere als das sein wird false. Auch indexOfist nicht unscharf, es ist in der Tat sehr klar definiert.
TJ Crowder

indexOfwird mit beiden übereinstimmen disconnectund connectwo in einem Fall, den ich erlebt habe, sind dies zwei verschiedene Fälle, für die ich Ergebnisse in einer Bedingung zurückgeben möchte.
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
   }
}

49

Einzeilige Lösung

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

Gibt true\falseif-Teilzeichenfolge zurückexists\does'nt exist

Benötigt ES6-Unterstützung


Tolle Lösung mit Pfeilfunktionen
GuerillaRadio

7
Ihr Kinder ... als ich ein Kind war, mussten wir diese Dinge verwenden, die als "for" -Schleifen bezeichnet wurden, und Sie mussten mehrere Zeilen verwenden und wissen, ob Ihr Array auf 1 oder Null basiert, ja ... die Hälfte der Zeit, die Sie hatten es war falsch und musste debuggen und nach einem kleinen Mistkerl namens 'i' Ausschau halten.
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
am einfachsten zu verstehen!
Daryl H

Außerdem wird das erste Vorkommen des Wortes in der Zeichenfolge zurückgegeben, was sehr hilfreich ist. Nicht nur ein wahr / falsch.
Kai Noack

20

Für Leute, die googeln,

Die solide Antwort sollte sein.

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
oder kürzer: if (substrings.some (v => v === str)) {
kofifus

10
Beachten Sie, dass dies eine Antwort auf eine etwas andere Frage, die fragt , ob eine Zeichenfolge enthält Text aus einem Array von Teilstrings. Dieser Code überprüft , ob ein String ist eine des Teils. Kommt darauf an, was mit "enthält" gemeint ist, nehme ich an.
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]
    }
}

edit: Wenn die Reihenfolge der Tests keine Rolle spielt, können Sie dies verwenden (mit nur einer Schleifenvariablen):

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

Ihr erstes Beispiel benötigt die lenVariable nicht, überprüfen Sie einfach i < arr.length.
GreySage

3

Wenn das Array nicht groß ist, können Sie die Zeichenfolge einfach mit jedem Teilstring einzeln schleifen und überprüfen indexOf(). Alternativ können Sie einen regulären Ausdruck mit Teilzeichenfolgen als Alternativen erstellen, die möglicherweise effizienter sind oder nicht.


Angenommen, wir haben eine Liste mit 100 Teilzeichenfolgen. Welcher Weg wäre effizienter: RegExp oder Schleife?
Diyorbek Sadullayev

3

Javascript-Funktion zum Durchsuchen eines Arrays von Tags oder Schlüsselwörtern mithilfe einer Suchzeichenfolge oder eines Arrays von Suchzeichenfolgen. (Uses ES5 einige Array - Verfahren und ES6 Pfeil Funktionen )

// 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;
}

Anwendungsbeispiel:

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

2

Nicht, dass ich vorschlagen würde, dass Sie gehen und erweitern / ändern String Prototyp , aber Folgendes habe ich getan:

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

Ausgehend von der Lösung von TJ Crowder habe ich einen Prototyp erstellt, um dieses Problem zu lösen:

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

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

Für volle Unterstützung;)


2

Die beste Antwort ist hier: Auch hier wird die Groß- und Kleinschreibung nicht berücksichtigt

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

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

1

Mit underscore.js oder lodash.js können Sie Folgendes für ein Array von Zeichenfolgen tun:

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

Und an einer einzigen Saite:

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

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

// true

1

Das ist super spät, aber ich bin gerade auf dieses Problem gestoßen. In meinem eigenen Projekt habe ich Folgendes verwendet, um zu überprüfen, ob sich eine Zeichenfolge in einem Array befindet:

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

Auf diese Weise können Sie ein vordefiniertes Array nehmen und prüfen, ob es eine Zeichenfolge enthält:

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

1

Aufbauend auf der Antwort von TJ Crowder

Verwenden von RegExp mit Escapezeichen, um zu testen, ob mindestens eine der Teilzeichenfolgen "mindestens einmal" vorkommt.

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

Wenn Sie mit einer langen Liste von Teilzeichenfolgen arbeiten, die aus vollständigen "Wörtern" bestehen, die durch Leerzeichen oder andere gemeinsame Zeichen getrennt sind, können Sie bei Ihrer Suche ein wenig klug sein.

Teilen Sie Ihre Zeichenfolge zuerst in Gruppen von X, dann X + 1, dann X + 2, ... bis zu Y. X und Y sollten die Anzahl der Wörter in Ihrer Teilzeichenfolge mit den wenigsten bzw. den meisten Wörtern sein. Wenn beispielsweise X 1 und Y 4 ist, wird "Alpha Beta Gamma Delta" zu:

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

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

"Alpha Beta Gamma" "Beta Gamma Delta"

"Alpha Beta Gamma Delta"

Wenn X 2 und Y 3 wäre, würden Sie die erste und letzte Zeile weglassen.

Jetzt können Sie diese Liste schnell durchsuchen, wenn Sie sie in ein Set (oder eine Map) einfügen, viel schneller als durch einen Zeichenfolgenvergleich.

Der Nachteil ist, dass Sie nicht nach Teilzeichenfolgen wie "ta Gamm" suchen können. Natürlich können Sie dies berücksichtigen, indem Sie nach Zeichen anstatt nach Wörtern aufteilen, aber dann müssen Sie häufig ein umfangreiches Set erstellen, und die dafür aufgewendete Zeit / Speicher überwiegt die Vorteile.


1

Für volle Unterstützung (zusätzlich zu den Versionen von @ricca ).

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


0

Sie können dies überprüfen:

<!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>

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.