Как найти индексы всех вхождений одной строки в другую в JavaScript?

Это может быть достигнуто путем:

var role_data = pm.response.json().results[0];
postman.setGlobalVariable(pm.environment.get("uuid"), role_data.role_category_id);
83
задан BiAiB 30 June 2016 в 15:12
поделиться

4 ответа

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

ОБНОВЛЕНИЕ

В исходном вопросе я не заметил, что строка поиска должна быть переменной. Я написал другую версию для этого случая, в которой используется indexOf , так что вы вернулись туда, откуда начали. Как указал Wrikken в комментариях, чтобы сделать это в общем случае с регулярными выражениями, вам нужно будет избегать специальных символов регулярного выражения, и в этот момент я думаю, что решение с регулярным выражением становится больше головной болью, чем оно того стоит.

 функция getIndicesOf (searchStr, str, caseSensitive) {var searchStrLen = searchStr.length; если (searchStrLen == 0) {return []; } var startIndex = 0, index, index = []; если (! caseSensitive) {str = str.toLowerCase (); searchStr = searchStr.toLowerCase (); } while ((index = str.indexOf (searchStr, startIndex))> -1) {index.push (индекс); startIndex = index + searchStrLen; } вернуть индексы; } var indices = getIndicesOf ("le", "Я научился играть на гавайской гитаре в Ливане."); document.getElementById ("output"). innerHTML = index + ""; 
 
141
ответ дан 24 November 2019 в 08:50
поделиться

Один лайнер с помощью String.protype.matchAll (ES2020):

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

Используя Ваши значения:

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]

, Если Вы волнуетесь по поводу выполнения распространения и map() в одной строке, я выполнил его с for...of цикл для миллиона повторений (использующий Ваши строки). Средние числа лайнера 1 420 мс, в то время как эти for...of средние числа 1 150 мс на моей машине. Это не незначительное различие, но один лайнер будет хорошо работать, если Вы только сделаете горстку соответствий.

См. matchAll на caniuse

0
ответ дан 24 November 2019 в 08:50
поделиться

Вот версия без регулярных выражений:

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

РЕДАКТИРОВАТЬ : и если вы хотите сопоставить такие строки, как 'aaaa' и 'aa', чтобы найти [0, 2], используйте эту версию:

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;
}
15
ответ дан 24 November 2019 в 08:50
поделиться

Вы точно можете это сделать!

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

Изменить: научиться писать RegExp

Кроме того, я понял, что это не совсем то, что вы хотите, поскольку lastIndex говорит нам о конце иглы, а не о ее начале, но это близко - вы можете вставить re.lastIndex-Needle.length в массив результатов ...

Изменить: добавление ссылки

Ответ @Tim Down использует объект результатов из RegExp.exec ( ), и все мои ресурсы Javascript замалчивают его использование (кроме предоставления вам совпадающей строки). Поэтому, когда он использует result.index , это что-то вроде безымянного Match Object. В описании MDC для exec этот объект описывается достаточно подробно.

12
ответ дан 24 November 2019 в 08:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: