Domanda

Sto cercando di trovare le posizioni di tutte le occorrenze di una stringa in un'altra stringa, maiuscole e minuscole.

Ad esempio, data la stringa:

I learned to play the Ukulele in Lebanon.

e il le stringa di ricerca, voglio ottenere il matrice:

[2, 25, 27, 33]

Entrambe le stringhe sarà variabili -. Vale a dire, non posso hard-code loro valori

Ho pensato che questo era un compito facile per le espressioni regolari, ma dopo aver lottato per un po 'per trovare uno che avrebbe funzionato, ho avuto fortuna.

questo esempio di come per ottenere questo risultato utilizzando .indexOf(), ma sicuramente ci deve essere un modo più conciso per farlo?

È stato utile?

Soluzione

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

Aggiorna

Non sono riuscito a individuare nella domanda iniziale che la stringa di ricerca deve essere una variabile. Ho scritto un'altra versione a che fare con questo caso che usi indexOf, quindi sei di nuovo al punto di partenza. Come le punte dai Wrikken nei commenti, per fare questo per il caso generale con le espressioni regolari si avrebbe bisogno di sfuggire caratteri speciali regex, a questo punto penso che la soluzione regex diventa più di un mal di testa che vale la pena.

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>

Altri suggerimenti

Questa è la versione gratuita regex:

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")

Modifica : e se si desidera far corrispondere stringhe come 'aaaa' e 'AA' per trovare [0, 2] utilizzare questa versione:

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

È sicuro che può fare questo!

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

Modifica: imparare a spell RegExp

Inoltre, ho capito che questo non è esattamente ciò che si vuole, come lastIndex ci racconta la fine del non dell'ago all'inizio, ma è vicino - si potrebbe spingere re.lastIndex-needle.length nella matrice risultati .. .

Modifica: Link aggiungendo

La risposta di @ Tim Giù utilizza i risultati oggetto da RegExp.exec (), e tutte le mie risorse JavaScript sorvolare il suo utilizzo (a parte dando la stringa corrispondente). Così, quando usa result.index, che è una sorta di senza nome Partita oggetto. Nella MDC descrizione exec , in realtà descrivono l'oggetto nei dettagli decente.

Se si desidera solo per trovare la posizione di tutte le partite mi piacerebbe puntare a un piccolo hack:

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)

potrebbe non essere applikable se si dispone di un RegExp con lunghezza variabile ma per alcuni potrebbe essere utile.

String.prototype.match .

Ecco un esempio dai MDN si docs:

var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
var regexp = /[A-E]/gi;
var matches_array = str.match(regexp);

console.log(matches_array);
// ['A', 'B', 'C', 'D', 'E', 'a', 'b', 'c', 'd', 'e']

Segui la risposta del @jcubic, la sua soluzione ha causato un piccolo confuso per il mio caso
Per esempio var result = indexes('aaaa', 'aa') tornerà [0, 1, 2] invece di [0, 2]
Così ho aggiornato un po 'la sua soluzione come indicato di seguito per abbinare il mio caso

function indexes(text, subText, caseSensitive) {
    var _source = text;
    var _find = subText;
    if (caseSensitive != true) {
        _source = _source.toLowerCase();
        _find = _find.toLowerCase();
    }
    var result = [];
    for (var i = 0; i < _source.length;) {
        if (_source.substring(i, i + _find.length) == _find) {
            result.push(i);
            i += _find.length;  // found a subText, skip to next position
        } else {
            i += 1;
        }
    }
    return result;
}

Ecco un semplice codice

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

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

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

Grazie per tutte le risposte. Sono andato attraverso tutti loro e si avvicinò con una funzione che dà il primo un ultimo indice di ogni occorrenza della sottostringa 'ago'. Vi metto qui nel caso che aiuterà qualcuno.

Si prega di notare, non è la stessa come la richiesta originale per solo l'inizio di ogni occorrenza. Si adatta al mio caso d'uso migliore, perché non è necessario per mantenere la lunghezza dell'ago.

function findRegexIndices(text, needle, caseSensitive){
  var needleLen = needle.length,
    reg = new RegExp(needle, caseSensitive ? 'gi' : 'g'),
    indices = [],
    result;

  while ( (result = reg.exec(text)) ) {
    indices.push([result.index, result.index + needleLen]);
  }
  return indices
}

il sottostante Codice farà il lavoro per voi:

function indexes(source, find) {
  var result = [];
  for(i=0;i<str.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("hello, how are you", "ar")
function countInString(searchFor,searchIn){

 var results=0;
 var a=searchIn.indexOf(searchFor)

 while(a!=-1){
   searchIn=searchIn.slice(a*1+searchFor.length);
   results++;
   a=searchIn.indexOf(searchFor);
 }

return results;

}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top