Wie finde ich Indizes aller Vorkommen einer Zeichenfolge in einer anderen in JavaScript?

Lesezeit: 7 Minuten

Wie finde ich Indizes aller Vorkommen einer Zeichenfolge in einer
Pfusch

Ich versuche, die Positionen aller Vorkommen einer Zeichenfolge in einer anderen Zeichenfolge ohne Berücksichtigung der Groß- und Kleinschreibung zu finden.

Zum Beispiel angesichts der Zeichenfolge:

I learned to play the Ukulele in Lebanon.

und die Suchzeichenfolge lemöchte ich das Array erhalten:

[2, 25, 27, 33]

Beide Zeichenfolgen werden Variablen sein – dh ich kann ihre Werte nicht fest codieren.

Ich dachte, dass dies eine leichte Aufgabe für reguläre Ausdrücke sei, aber nachdem ich eine Weile darum gekämpft hatte, einen funktionierenden zu finden, hatte ich kein Glück.

ich fand dieses Beispiel wie Sie dies erreichen können .indexOf()aber es muss doch doch einen kürzeren Weg geben?

1644107766 630 Wie finde ich Indizes aller Vorkommen einer Zeichenfolge in einer
Tim unten

var str = "I learned to play the Ukulele in Lebanon."
var regex = /le/gi, result, indices = [];
while ( (result = regex.exec(str)) ) {
    indices.push(result.index);
}

AKTUALISIEREN

Ich habe in der ursprünglichen Frage nicht erkannt, dass die Suchzeichenfolge eine Variable sein muss. Ich habe eine andere Version geschrieben, um diesen Fall zu behandeln, der verwendet indexOf, Sie sind also wieder da, wo Sie angefangen haben. Wie Wrikken in den Kommentaren darauf hingewiesen hat, müssten Sie, um dies für den allgemeinen Fall mit regulären Ausdrücken zu tun, spezielle Regex-Zeichen maskieren. An diesem Punkt denke ich, dass die Regex-Lösung mehr Kopfschmerzen bereitet, als sie wert ist.

function getIndicesOf(searchStr, str, caseSensitive) {
    var searchStrLen = searchStr.length;
    if (searchStrLen == 0) {
        return [];
    }
    var startIndex = 0, index, indices = [];
    if (!caseSensitive) {
        str = str.toLowerCase();
        searchStr = searchStr.toLowerCase();
    }
    while ((index = str.indexOf(searchStr, startIndex)) > -1) {
        indices.push(index);
        startIndex = index + searchStrLen;
    }
    return indices;
}

var indices = getIndicesOf("le", "I learned to play the Ukulele in Lebanon.");

document.getElementById("output").innerHTML = indices + "";
<div id="output"></div>

  • Wie würde le eine variable Zeichenfolge hier sein? Auch beim Benutzen new Regexp(str); die Gefahr von Sonderzeichen lauert, sucht $2.50 zum Beispiel. Etwas wie regex = new Regexp(dynamicstring.replace(/([\.+*?\[^\]$(){}=!<>|:])/g, '\$1')); wäre mehr in der Nähe IMHO. Ich bin mir nicht sicher, ob js einen eingebauten Regex-Escape-Mechanismus hat.

    – Wrikken

    4. August 10 um 23:35 Uhr


  • … ah, ich verstehe: Ich habe in der Frage nicht erkannt, dass das OP dieses Maß an Allgemeingültigkeit benötigt. Umschreiben…

    – Tim unten

    4. August 10 um 23:45 Uhr

  • Tolle Antwort und sehr hilfreich. Vielen Dank Tim!

    – Pfusch

    5. August 10 um 0:38 Uhr

  • Wenn die Suchzeichenfolge eine leere Zeichenfolge ist, erhalten Sie eine Endlosschleife … würde eine Überprüfung durchführen.

    – HelpMeStackOverflowMyOnlyHope

    20. September 16 um 1:10 Uhr

  • Vermuten searchStr=aaa und das str=aaaaaa. Anstatt 4 Vorkommen zu finden, findet Ihr Code dann nur 2, weil Sie vorbeispringen searchStr.length in der Schleife.

    – lodert

    18. Oktober 17 um 10:35 Uhr


Wie finde ich Indizes aller Vorkommen einer Zeichenfolge in einer
Benni Hinrichs

Ein Liner mit String.protype.matchAll (ES2020):

[...sourceStr.matchAll(new RegExp(searchStr, 'gi'))].map(a => a.index)

Verwenden Sie Ihre Werte:

const sourceStr="I learned to play the Ukulele in Lebanon.";
const searchStr="le";
const indexes = [...sourceStr.matchAll(new RegExp(searchStr, 'gi'))].map(a => a.index);
console.log(indexes); // [2, 25, 27, 33]

Wenn Sie sich Sorgen machen, einen Spread zu machen und a map() In einer Zeile habe ich es mit a ausgeführt for...of Loop für eine Million Iterationen (mit Ihren Strings). Der Einzeiler dauert durchschnittlich 1420 ms, während der for...of durchschnittlich 1150 ms auf meiner Maschine. Das ist kein unbedeutender Unterschied, aber der Einzeiler wird gut funktionieren, wenn Sie nur eine Handvoll Spiele machen.

Sehen matchAll auf canius

Wie finde ich Indizes aller Vorkommen einer Zeichenfolge in einer
jkubisch

Hier ist die Regex-freie Version:

function indexes(source, find) {
  if (!source) {
    return [];
  }
  // if find is empty string return all indexes.
  if (!find) {
    // or shorter arrow function:
    // return source.split('').map((_,i) => i);
    return source.split('').map(function(_, i) { return i; });
  }
  var result = [];
  for (i = 0; i < source.length; ++i) {
    // If you want to search case insensitive use 
    // if (source.substring(i, i + find.length).toLowerCase() == find) {
    if (source.substring(i, i + find.length) == find) {
      result.push(i);
    }
  }
  return result;
}

indexes("I learned to play the Ukulele in Lebanon.", "le")

BEARBEITEN: und wenn Sie übereinstimmende Zeichenfolgen wie ‘aaaa’ und ‘aa’ finden möchten [0, 2] verwende diese Version:

function indexes(source, find) {
  if (!source) {
    return [];
  }
  if (!find) {
      return source.split('').map(function(_, i) { return i; });
  }
  var result = [];
  var i = 0;
  while(i < source.length) {
    if (source.substring(i, i + find.length) == find) {
      result.push(i);
      i += find.length;
    } else {
      i++;
    }
  }
  return result;
}

  • +1. Ich habe einige Tests zum Vergleich mit einer Lösung mit Regex durchgeführt. Die schnellste Methode war die mit Regex: jsperf.com/javascript-find-all

    – StuR

    8. Mai 13 um 11:11 Uhr

  • Die schnellste Methode ist die Verwendung von indexOf jsperf.com/find-o-substrings

    – Ethan Yanjia Li

    16. April 18 um 3:13 Uhr


  • @LiEthan Es spielt nur eine Rolle, ob diese Funktion ein Engpass ist und möglicherweise die Eingabezeichenfolge lang ist.

    – jkubisch

    16. April 18 um 11:52 Uhr


  • @jcubic Deine Lösung scheint gut zu sein, hat aber nur eine kleine Verwirrung. Was ist, wenn ich die Funktion so aufrufe? var result = indexes('aaaa', 'aa')? Das erwartete Ergebnis sollte sein [0, 1, 2] oder [0, 2]?

    – Cao Mạnh Quang

    19. April 18 um 7:01 Uhr


  • @CaoMạnhQuang beim Betrachten des Codes das erste Ergebnis. Wenn Sie die zweite möchten, müssen Sie eine While-Schleife erstellen und innen, wenn Sie sie einfügen i+=find.length; und sonst i++

    – jkubisch

    19. April 18 um 13:43 Uhr

1644107767 276 Wie finde ich Indizes aller Vorkommen einer Zeichenfolge in einer
Ryley

Sie können das sicher tun!

//make a regular expression out of your needle
var needle="le"
var re = new RegExp(needle,'gi');
var haystack = 'I learned to play the Ukulele';

var results = new Array();//this is the results you want
while (re.exec(haystack)){
  results.push(re.lastIndex);
}

Bearbeiten: Lernen Sie, RegExp zu buchstabieren

Außerdem wurde mir klar, dass dies nicht der Fall ist exakt was du willst, wie lastIndex Das Ende der Nadel sagt uns nicht den Anfang, aber es ist nah – man könnte schieben re.lastIndex-needle.length in das Ergebnisfeld …

Edit: Link hinzugefügt

Die Antwort von @Tim Down verwendet das Ergebnisobjekt von RegExp.exec(), und alle meine Javascript-Ressourcen beschönigen seine Verwendung (abgesehen davon, dass Sie die übereinstimmende Zeichenfolge erhalten). Also, wenn er verwendet result.index, das ist eine Art unbenanntes Match-Objekt. Im MDC-Beschreibung von execsie beschreiben dieses Objekt tatsächlich in anständigen Details.

1644107767 509 Wie finde ich Indizes aller Vorkommen einer Zeichenfolge in einer
Hoffmann

Wenn Sie nur die Position aller Übereinstimmungen finden möchten, möchte ich Sie auf einen kleinen Hack hinweisen:

var haystack = 'I learned to play the Ukulele in Lebanon.',
    needle="le",
    splitOnFound = haystack.split(needle).map(function (culm)
    {
        return this.pos += culm.length + needle.length
    }, {pos: -needle.length}).slice(0, -1); // {pos: ...} – Object wich is used as this

console.log(splitOnFound);

Es ist möglicherweise nicht anwendbar, wenn Sie einen RegExp mit variabler Länge haben, aber für einige kann es hilfreich sein.

Hierbei wird zwischen Groß- und Kleinschreibung unterschieden. Für die Verwendung ohne Berücksichtigung der Groß-/Kleinschreibung String.toLowerCase Funktion vor.

  • Ich denke, Ihre Antwort ist die beste, da die Verwendung von RegExp gefährlich ist.

    – Bharata

    25. Juli 2020 um 12:13 Uhr

1644107768 412 Wie finde ich Indizes aller Vorkommen einer Zeichenfolge in einer
Scaramouche

Ich bin ein bisschen zu spät zur Party (um fast 10 Jahre, 2 Monate), aber eine Möglichkeit für zukünftige Programmierer besteht darin, dies mit der While-Schleife und zu tun indexOf()

let haystack = "I learned to play the Ukulele in Lebanon.";
let needle = "le";
let pos = 0; // Position Ref
let result = []; // Final output of all index's.
let hayStackLower = haystack.toLowerCase();

// Loop to check all occurrences 
while (hayStackLower.indexOf(needle, pos) != -1) {
  result.push(hayStackLower.indexOf(needle , pos));
  pos = hayStackLower.indexOf(needle , pos) + 1;
}

console.log("Final ", result); // Returns all indexes or empty array if not found

  • Ich denke, Ihre Antwort ist die beste, da die Verwendung von RegExp gefährlich ist.

    – Bharata

    25. Juli 2020 um 12:13 Uhr

1644107768 261 Wie finde ich Indizes aller Vorkommen einer Zeichenfolge in einer
Tech-Experten-Assistent

Hier ist ein einfaches Code-Snippet:

function getIndexOfSubStr(str, searchToken, preIndex, output) {
    var result = str.match(searchToken);
    if (result) {
        output.push(result.index +preIndex);
        str=str.substring(result.index+searchToken.length);
        getIndexOfSubStr(str, searchToken, preIndex, output)
    }
    return output;
}

var str = "my name is 'xyz' and my school name is 'xyz' and my area name is 'xyz' ";
var searchToken ="my";
var preIndex = 0;

console.log(getIndexOfSubStr(str, searchToken, preIndex, []));

.

790100cookie-checkWie finde ich Indizes aller Vorkommen einer Zeichenfolge in einer anderen in JavaScript?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy