[removed] How to get multiple matches in RegEx .exec results

后端 未结 6 1572
遥遥无期
遥遥无期 2020-12-09 02:54

When I run

/(a)/g.exec(\'a a a \').length

I get

2

but I thought it should return

3


        
相关标签:
6条回答
  • 2020-12-09 02:58

    You could use match instead:

    'a a a'.match(/(a)/g).length  // outputs: 3
    
    0 讨论(0)
  • 2020-12-09 02:59

    You are only matching the first a. The reason the length is two is that it is finding the first match and the parenthesized group part of the first match. In your case they are the same.

    Consider this example.

    var a = /b(a)/g.exec('ba ba ba ');
    alert(a);
    

    It outputs ba, a. The array length is still 2, but it is more obvious what is going on. "ba" is the full match. a is the parenthesized first grouping match.

    The MDN documentation supports this - that only the first match and contained groups are returned. To find all matches, you'd use match() as stated by mVChr.

    0 讨论(0)
  • 2020-12-09 03:00

    exec() is returning only the set of captures for the first match, not the set of matches as you expect. So what you're really seeing is $0 (the entire match, "a") and $1 (the first capture)--i.e. an array of length 2. exec() meanwhile is designed so that you can call it again to get the captures for the next match. From MDN:

    If your regular expression uses the "g" flag, you can use the exec method multiple times to find successive matches in the same string. When you do so, the search starts at the substring of str specified by the regular expression's lastIndex property (test will also advance the lastIndex property).

    0 讨论(0)
  • 2020-12-09 03:06

    Code:

    alert('a a a'.match(/(a)/g).length);
    

    Output:

    3
    
    0 讨论(0)
  • 2020-12-09 03:06

    regexp.exec(str) returns the first match or the entire match and the first capture (when re = /(a)/g; ) as mentionned in other answers

    const str = 'a a a a a a a a a a a a a';
    const re = /a/g;
    
    const result = re.exec(str);
    console.log(result);

    But it also remembers the position after it in regexp.lastIndex property.

    The next call starts to search from regexp.lastIndex and returns the next match.

    If there are no more matches then regexp.exec returns null and regexp.lastIndex is set to 0.

    const str = 'a a a';
    const re = /a/g;
    
    const a = re.exec(str);
    console.log('match : ', a, ' found at : ', re.lastIndex);
    
    const b = re.exec(str);
    console.log('match : ', b, ' found at : ', re.lastIndex);
    
    const c = re.exec(str);
    console.log('match : ', c, ' found at : ', re.lastIndex);
    
    const d = re.exec(str);
    console.log('match : ', d, ' found at : ', re.lastIndex);
    
    const e = re.exec(str);
    console.log('match : ', e, ' found at : ', re.lastIndex);

    That's why you can use a while loop that will stop when the match is null

    const str = 'a a a';
    const re = /a/g;
    
    while(match = re.exec(str)){
      console.log(match, ' found at : ', match.index); 
    }

    0 讨论(0)
  • 2020-12-09 03:08

    while loop can help you

    x = 'a a a a';
    y = new RegExp(/a/g);
    while(null != (z=y.exec(x))) {
       console.log(z);     // output: object
       console.log(z[0]);  // ouput: "a"
    }
    

    If you add counter then you get length of it.

    x = 'a a a a';
    counter = 0;
    y = new RegExp(/a/g);
    while(null != (z=y.exec(x))) {
       console.log(z);     // output: object
       console.log(z[0]);  // output: "a"
       counter++;
    }
    console.log(counter);  // output: 4
    

    This is quite safe, even if it doesn't find any matching then it just exits and counter will be 0

    Main intention is to tell how RegExp can be used to loop and get all values from string of same matched RegExp

    0 讨论(0)
提交回复
热议问题