返回正则表达式match()在Javascript中的位置?


Answers:


225

exec返回具有index属性的对象:

var match = /bar/.exec("foobar");
if (match) {
    console.log("match found at " + match.index);
}

对于多个匹配项:

var re = /bar/g,
    str = "foobarfoobar";
while ((match = re.exec(str)) != null) {
    console.log("match found at " + match.index);
}


5
谢谢你的帮助!您还能告诉我如何找到多个匹配项的索引吗?
stagas 2010年

9
注意:使用reas作为变量并添加g修饰符都是至关重要的!否则,您将陷入无尽的循环。
oriadam

1
@OnurYıldırım-这是一个正在工作的jsfiddle ...我已经对其进行了测试,直到IE5 ...效果很好:jsfiddle.net/6uwn1vof
Jimbo Jonny

1
@JimboJonny,嗯,我学到了一些新东西。我的测试用例返回undefinedjsfiddle.net/6uwn1vof/2 ,这不是像您一样的类似于搜索的示例。
OnurYıldırım2016年

1
@OnurYıldırım-删除g标志,它将起作用。由于match是字符串的函数,而不是正则表达式exec,因此它不能像一样是有状态的,因此,exec如果您不查找全局匹配项,则它仅将其视为(即具有index属性)...因为有状态无关紧要。
Jimbo Jonny

60

这是我想出的:

// Finds starting and ending positions of quoted text
// in double or single quotes with escape char support like \" \'
var str = "this is a \"quoted\" string as you can 'read'";

var patt = /'((?:\\.|[^'])*)'|"((?:\\.|[^"])*)"/igm;

while (match = patt.exec(str)) {
  console.log(match.index + ' ' + patt.lastIndex);
}


17
match.index + match[0].length也适用于最终位置。
贝尼·切尔尼亚夫斯基-帕斯金


1
@ BeniCherniavsky-Paskin,结束位置不是match.index + match[0].length - 1吗?
大卫

1
@David,我的意思是排他性的结束位置,例如.slice().substring()。如您所说,包容性结局要少1。(请注意,“包含”通常表示比赛中最后一个char的索引,除非它是比赛之前为 1的空比赛,并且可能-1在开始时完全在字符串之外以表示空比赛...)
Beni Cherniavsky-Paskin

16

来自developer.mozilla.org文档的String .match()方法:

返回的Array有一个额外的input属性,其中包含已解析的原始字符串。此外,它还具有index属性,该属性表示string中匹配项的从零开始的索引

当处理非全局正则表达式时(即,g正则表达式上没有标志),返回的值.match()具有index属性...您要做的就是访问它。

var index = str.match(/regex/).index;

这是一个示例,它也可以正常工作:

var str = 'my string here';

var index = str.match(/here/).index;

alert(index); // <- 10

回到IE5,我已经成功地进行了测试。



6

这是我最近发现的一项很酷的功能,我在控制台上尝试了一下,它似乎可以正常工作:

var text = "border-bottom-left-radius";

var newText = text.replace(/-/g,function(match, index){
    return " " + index + " ";
});

其中返回:“边界6底13左18半径”

所以这似乎是您要寻找的。


6
请注意,替换功能也会添加捕获组,因此请注意,位置始终是替换功能中倒数第二个条目arguments。不是“第二个论点”。函数参数为“完全匹配,组1,组2,...,匹配索引,与之匹配的完整字符串”
Mike'Pomax'Kamermans

1

该成员fn返回String对象内输入单词的从0开始的位置数组(如果有)

String.prototype.matching_positions = function( _word, _case_sensitive, _whole_words, _multiline )
{
   /*besides '_word' param, others are flags (0|1)*/
   var _match_pattern = "g"+(_case_sensitive?"i":"")+(_multiline?"m":"") ;
   var _bound = _whole_words ? "\\b" : "" ;
   var _re = new RegExp( _bound+_word+_bound, _match_pattern );
   var _pos = [], _chunk, _index = 0 ;

   while( true )
   {
      _chunk = _re.exec( this ) ;
      if ( _chunk == null ) break ;
      _pos.push( _chunk['index'] ) ;
      _re.lastIndex = _chunk['index']+1 ;
   }

   return _pos ;
}

现在尝试

var _sentence = "What do doers want ? What do doers need ?" ;
var _word = "do" ;
console.log( _sentence.matching_positions( _word, 1, 0, 0 ) );
console.log( _sentence.matching_positions( _word, 1, 1, 0 ) );

您还可以输入正则表达式:

var _second = "z^2+2z-1" ;
console.log( _second.matching_positions( "[0-9]\z+", 0, 0, 0 ) );

这里得到线性项的位置索引。


1
var str = "The rain in SPAIN stays mainly in the plain";

function searchIndex(str, searchValue, isCaseSensitive) {
  var modifiers = isCaseSensitive ? 'gi' : 'g';
  var regExpValue = new RegExp(searchValue, modifiers);
  var matches = [];
  var startIndex = 0;
  var arr = str.match(regExpValue);

  [].forEach.call(arr, function(element) {
    startIndex = str.indexOf(element, startIndex);
    matches.push(startIndex++);
  });

  return matches;
}

console.log(searchIndex(str, 'ain', true));

这是不正确的。str.indexOf这里只是找到匹配项捕获的文本的下一个匹配项,不一定是匹配项。JS正则表达式支持超前捕获的文本条件。例如searchIndex("foobarfoobaz", "foo(?=baz)", true)应该给[6],而不是[0]
rakslice

为什么`[] .forEach.call(arr,function(element)`为什么不是arr.forEach或arr.map
Ankit Kumar,

1

在现代浏览器中,您可以使用string.matchAll()完成此操作

@Gumbo的答案中RegExp.exec()一样,此方法vs的好处是它不依赖于正则表达式是有状态

let regexp = /bar/g;
let str = 'foobarfoobar';

let matches = [...str.matchAll(regexp)];
matches.forEach((match) => {
    console.log("match found at " + match.index);
});


-1
function trimRegex(str, regex){
    return str.substr(str.match(regex).index).split('').reverse().join('').substr(str.match(regex).index).split('').reverse().join('');
}

let test = '||ab||cd||';
trimRegex(test, /[^|]/);
console.log(test); //output: ab||cd

要么

function trimChar(str, trim, req){
    let regex = new RegExp('[^'+trim+']');
    return str.substr(str.match(regex).index).split('').reverse().join('').substr(str.match(regex).index).split('').reverse().join('');
}

let test = '||ab||cd||';
trimChar(test, '|');
console.log(test); //output: ab||cd
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.