我试图找到一个字符串的所有出现在另一个字符串的位置,不区分大小写。

例如,给定的字符串:

I learned to play the Ukulele in Lebanon.

和搜索字符串le,我想获得数组:

[2, 25, 27, 33]

两个字符串将是变量 - 即,我不能硬编码它们的值

我想,这是对正则表达式一件容易的事,但挣扎了一会儿,找到一个会的工作后,我有没有运气。

我发现本实施例的如何做到这一点使用 .indexOf(),但肯定必须有一个更简洁的方式来做到这一点?

有帮助吗?

解决方案

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指出,要对正则表达式,你将需要转义特殊的正则表达式字符,在这一点,我认为正则表达式的解决方案变得更加头疼的比它的价值一般情况下做到这一点。

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>

其他提示

下面是正则表达式分类版本:

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

您肯定能做到这一点!

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

修改:学习拼写正则表达式

另外,我意识到这不是的究竟的你想要什么,因为lastIndex告诉我们针不是开始的结束,但它很接近 - 你可以推re.lastIndex-needle.length到结果阵列..

修改:将链接

@Tim唐氏答案使用结果从RegExp.exec()对象,以及我所有的JavaScript资源粉饰其使用(除了给你匹配的字符串)。所以,当他用result.index,这是某种不知名的匹配对象。在EXEC 的 MDC介绍,他们实际描述这个对象体面的细节。

如果你只是想找到我想你指向一个小黑客所有匹配的位置:

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)

这可能不是applikable如果你有可变长度的一个RegExp但对于有些人来说可能会有所帮助。

使用 String.prototype.match

下面是从MDN文档本身的示例:

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

请@jcubic的答案,他的解决方案引起了不小的迷惑我的情况下点击 例如var result = indexes('aaaa', 'aa')它将返回[0, 1, 2]代替[0, 2]结果的 所以,我更新了一下他的解决方案如下符合我的情况下,点击

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

下面是一个简单的代码

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, []));

感谢所有答复。我经历了所有的人去了,与给人的第一“针”串的每次出现的最后一个索引的功能上来。我在这里张贴的情况下,它会帮助别人。

请注意,这是不一样的每次出现的只是开始的原始请求。它适合我的用例更好,因为你不需要保持针的长度。

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
}

下面的代码将做的工作适合你:

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;

}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top