在javascript中,是否有一个string . indexof()的等效,为第一个参数接受正则表达式而不是字符串,同时仍然允许第二个参数?

我需要做点什么

str.indexOf(/[abc]/ , i);

and

str.lastIndexOf(/[abc]/ , i);

虽然String.search()接受regexp作为参数,但它不允许我指定第二个参数!

编辑: 这比我最初想象的要难,所以我写了一个小测试函数来测试所有提供的解决方案……它假设regexIndexOf和regexLastIndexOf已经添加到String对象中。

function test (str) {
    var i = str.length +2;
    while (i--) {
        if (str.indexOf('a',i) != str.regexIndexOf(/a/,i)) 
            alert (['failed regexIndexOf ' , str,i , str.indexOf('a',i) , str.regexIndexOf(/a/,i)]) ;
        if (str.lastIndexOf('a',i) != str.regexLastIndexOf(/a/,i) ) 
            alert (['failed regexLastIndexOf ' , str,i,str.lastIndexOf('a',i) , str.regexLastIndexOf(/a/,i)]) ;
    }
}

我正在进行如下测试,以确保至少对于一个字符regexp,如果我们使用indexOf,结果是相同的

在 xes 中寻找 a 测试(“xxx”); 测试('axx'); 测试(“xax”); 测试(“XXA”); 测试(“AXA”); 测试(“xaa”); 测试(“AAX”); 测试(“AAA”);


当前回答

你可以使用String.prototype.matchAll()和方便的Array.prototype.at():

const str = "foo a foo B"; const matches =[…str.matchAll(/[abc]/gi)]; If (matches.length) { const indexOfFirstMatch = matches.at(0).index; const indexOfLastMatch = matches.at(-1).index; console.log (indexOfFirstMatch indexOfLastMatch) }

其他回答

让正则表达式;//你的RegExp 加勒比海盗。map(x => !!x. tostring ().match(regExp)).indexOf(true)

你可以使用substr。

str.substr(i).match(/[abc]/);

String构造函数的实例有一个.search()方法,该方法接受RegExp并返回第一个匹配项的索引。

要从特定位置开始搜索(伪造.indexOf()的第二个参数),可以切掉前i个字符:

str.slice(i).search(/re/)

但这将获得较短字符串的索引(在第一部分被切掉之后),因此如果返回的索引不是-1,则需要将切掉的部分(i)的长度添加到返回的索引中。这将给你原始字符串的索引:

function regexIndexOf(text, re, i) {
    var indexInSuffix = text.slice(i).search(re);
    return indexInSuffix < 0 ? indexInSuffix : indexInSuffix + i;
}

好吧,因为你只是想匹配字符的位置,regex可能是多余的。

我假设你想要的不是,找到这些字符中的第一个,而是找到这些字符中的第一个。

这当然是一个简单的答案,但做到了你的问题所要做的事情,尽管没有正则表达式部分(因为你没有明确说明为什么它必须是一个正则表达式)

function mIndexOf( str , chars, offset )
{
   var first  = -1; 
   for( var i = 0; i < chars.length;  i++ )
   {
      var p = str.indexOf( chars[i] , offset ); 
      if( p < first || first === -1 )
      {
           first = p;
      }
   }
   return first; 
}
String.prototype.mIndexOf = function( chars, offset )
{
   return mIndexOf( this, chars, offset ); # I'm really averse to monkey patching.  
};
mIndexOf( "hello world", ['a','o','w'], 0 );
>> 4 
mIndexOf( "hello world", ['a'], 0 );
>> -1 
mIndexOf( "hello world", ['a','o','w'], 4 );
>> 4
mIndexOf( "hello world", ['a','o','w'], 5 );
>> 6
mIndexOf( "hello world", ['a','o','w'], 7 );
>> -1 
mIndexOf( "hello world", ['a','o','w','d'], 7 );
>> 10
mIndexOf( "hello world", ['a','o','w','d'], 10 );
>> 10
mIndexOf( "hello world", ['a','o','w','d'], 11 );
>> -1

对于具有稀疏匹配的数据,使用字符串。跨浏览器搜索速度最快。它每次迭代都会重新切片字符串:

function lastIndexOfSearch(string, regex, index) {
  if(index === 0 || index)
     string = string.slice(0, Math.max(0,index));
  var idx;
  var offset = -1;
  while ((idx = string.search(regex)) !== -1) {
    offset += idx + 1;
    string = string.slice(idx + 1);
  }
  return offset;
}

对于密集的数据,我做了这个。与执行方法相比,它比较复杂,但对于密集数据,它比我尝试过的其他方法快2-10倍,比公认的解决方案快100倍左右。要点如下:

It calls exec on the regex passed in once to verify there is a match or quit early. I do this using (?= in a similar method, but on IE checking with exec is dramatically faster. It constructs and caches a modified regex in the format '(r).(?!.?r)' The new regex is executed and the results from either that exec, or the first exec, are returned; function lastIndexOfGroupSimple(string, regex, index) { if (index === 0 || index) string = string.slice(0, Math.max(0, index + 1)); regex.lastIndex = 0; var lastRegex, index flags = 'g' + (regex.multiline ? 'm' : '') + (regex.ignoreCase ? 'i' : ''), key = regex.source + '$' + flags, match = regex.exec(string); if (!match) return -1; if (lastIndexOfGroupSimple.cache === undefined) lastIndexOfGroupSimple.cache = {}; lastRegex = lastIndexOfGroupSimple.cache[key]; if (!lastRegex) lastIndexOfGroupSimple.cache[key] = lastRegex = new RegExp('.*(' + regex.source + ')(?!.*?' + regex.source + ')', flags); index = match.index; lastRegex.lastIndex = match.index; return (match = lastRegex.exec(string)) ? lastRegex.lastIndex - match[1].length : index; };

方法的jsPerf

我不明白上面这些测试的目的。需要正则表达式的情况是不可能与调用indexOf进行比较的,我认为这是首先创建该方法的目的。为了让测试通过,使用'xxx+(?!x)'比调整regex迭代的方式更有意义。