Some supplementary learning of re

match.matchAllandexecThe difference between

  • Match, matchAll on strings, exec on regular expressions

  • Match returns an array of all matched characters when matching a g pattern re.

    Matching a non-G-mode re returns the first array that is matched, and the rest is the string captured in parentheses.

  • The array returned by exec matching g mode re is the same as that returned by match matching non-G mode re.

    In G mode, exec records the match, recording the position since the last successful match in the lastIndex property of the regular expression, and the next match will start from there.

  • MatchAll can only match g patterns and returns an iterator, which can be passed by for… The of array. from destruct operator, whose return values are collected as arrays and all of exec’s returns are collected together, each of which is the return value of a match in a non-G mode.

let str = "abcde abcde abcd";
const Aregexp = /(abc)d(e)/g;
const Bregexp = /(abc)d(e)/;

console.log(str.match(Aregexp)); / /? [abcde abcde]
console.log(str.match(Bregexp)); / /? [abcde abc e]

console.log(Aregexp.exec(str)); / /? [abcde abc e]
console.log(Aregexp.exec(str)); / /? [abcde abc e]
console.log(Aregexp.exec(str)); / /? null
console.log(Bregexp.exec(str)); / /? [abcde abc e]
console.log(Bregexp.exec(str)); / /? [abcde abc e]

console.log(... str.matchAll(Aregexp));/ /? [abcde abc e] [abcde abc e]
console.log(... str.matchAll(Bregexp));/ /! Error can only match g mode
Copy the code

(? :x)Non-capture parenthesis

This has nothing to do with the match of the re. When encountered, you can simply ignore the symbol and concatenate the character with the following one.

let str = "abcdbd";
const Aregexp = / (? :abc)d/;
const Bregexp = /abcd/;
console.log(str.replace(Aregexp, "")); / /? bd
console.log(str.replace(Bregexp, "")); / /? bd
Copy the code

It’s the same thing.

But the result of matching is different, by (? Exec and match will not be matched separately:

let str = "abcdb";
const Aregexp = / (? :abc)(d)b/;
const Bregexp = /(abc)(d)b/;

console.log(Aregexp.exec(str)); / /? abcdb b
console.log(Bregexp.exec(str)); / /? abcdb abc d
Copy the code

This symbol is a special form of parentheses. Groups enclosed in parentheses are recorded as $n for ease of use, but groups enclosed in parentheses are not recorded:

let str = "abcdbd";
const Aregexp = / (? :abc)(d)b\1/; / /! '\x' will be regarded as the contents of the x parenthesis, which is equivalent to \abcdbd\
const Bregexp = /(abc)(d)b\1/; / /! This is equivalent to \abcdbabc\

console.log(str.replace(Aregexp, "")); / /? Empty is replaced because '(? :) 'will not be recorded
console.log(str.replace(Bregexp, "")); / /? abcdbd

let strs = "abcdbabc";
console.log(strs.replace(Bregexp, "")); / /? I've replaced everything

/ /! In the same way, $x in replace is not recorded
console.log(str.replace(Aregexp, "$2 $1")); / /? $2 d
console.log(strs.replace(Bregexp, "$2 $1")); / /? d abc
Copy the code

(? <name>)Named group card

This symbol and the above (? : is a special modifier for parentheses, which generates a groups attribute in the matching result, using the object’s key-value pair to record the matching result in parentheses:

let str = "abcdb";
const Aregexp = / (? 
      
       abc)(? 
       
        d)/
       
      ;
console.log(Aregexp.exec(str));
/* groups:{ first:"abc", secend:"d", } */
Copy the code

This matching form is useful when you need to replace multiple possible characters.

Take a look at the second argument to replace, which accepts a callback function that returns the string for each match to be replaced:

let str = "abcdb"
const Bregexp = /abc/;

console.log(
    str.replace(Bregexp, () = > {
        return ""; }));/ /? bd
Copy the code

This function takes more than one argument, as shown in MDN. You can use the destruct operator to extract groups:

let str = "abcabcdb";

const Aregexp = / (? 
      
       abc)|(? 
       
        d)/g
       
      ;

const result = str.replace(Aregexp, (. arg) = > {
    const groups = JSON.parse(JSON.stringify(arg.pop())); / /! This removes empty attributes that are not matched
    if (groups.first) {
        return "zzz";
    } else if (groups.secend) {
        return "ddd"; }});console.log(result); / /? zzzzzzdddb
Copy the code