В чем разница между функцией exec() регулярного выражения и функцией match() строки?



если я запустил это:



/([^/]+)+/g.exec('/a/b/c/d');


Я получаю это:



["a", "a"]


но если я запускаю этот:



'/a/b/c/d'.match(/([^/]+)+/g);


тогда я получаю ожидаемый результат этого:



["a", "b", "c", "d"]


какая разница?

738   5  

5 ответов:

exec с глобальным регулярным выражением предназначено для использования в цикле, так как оно все равно будет извлекать все соответствующие подвыражения. Итак:

var re = /[^\/]+/g;
var match;

while (match = re.exec('/a/b/c/d')) {
    // match is now the next match, in array form.
}

// No more matches.

String.match делает это за вас и отбрасывает захваченные группы.

одна картинка лучше, вы знаете...

re_once = /([a-z])([A-Z])/
re_glob = /([a-z])([A-Z])/g

st = "aAbBcC"

console.log("match once="+ st.match(re_once)+ "  match glob="+ st.match(re_glob))
console.log("exec once="+ re_once.exec(st) + "   exec glob="+ re_glob.exec(st))
console.log("exec once="+ re_once.exec(st) + "   exec glob="+ re_glob.exec(st))
console.log("exec once="+ re_once.exec(st) + "   exec glob="+ re_glob.exec(st))

видите разницу?

Примечание: чтобы выделить, обратите внимание, что захваченные группы(например: a, A) возвращаются после совпадающего шаблона (например: aA), это не просто совпадающий шаблон.

/regex/.exec() возвращает только первое найденное совпадение, в то время как "string".match() возвращает все из них, если вы используете g флаг в регулярном выражении.

смотрите здесь: exec,матч.

Если ваше регулярное выражение является глобальным, и вы захватываете, то вы должны использовать exec. Матч не вернет все ваши снимки.

матч отлично работает, когда просто совпадение (не захват). Вы запускаете его один раз, и он дает массив всех совпадений. (хотя если регулярное выражение не является глобальным, то match покажет совпадение с последующим захватом)

Exec-это то, что вы используете при захвате, и каждый раз, когда он выполняется, он дает совпадение, а затем захватывает. (матч будет ведите себя таким образом, чтобы дать полное совпадение с последующим захватом, только когда регулярное выражение не является глобальным).

другое использование с Exec, это получение индекса или позиции, совпадения. Если у вас есть переменная для вашего регулярного выражения, вы можете использовать .lastIndex и получить позицию соответствия. Объект regex имеет .lastIndex и объект regex - это то, что вы делаете .старпом включен. Точка матче делается на веревочке и вы не сможете потом сделать регулярное выражение объект, точка, свойство lastindex

строка, имеет функция соответствия, которая передается регулярным выражением. И регулярное выражение, имеет функцию exec, и передается строка

exec вы запускаете несколько раз. матч вы запускаете один раз

Это хорошо, чтобы использовать матч, когда не захватывая и при съемке вы можете использовать метод exec, который является более мощным, так как он хорошо фиксирует, но если вы использовали матч при съемке, вижу, что это шоу захватывает, когда регулярное выражение не является глобальной, но не захватывает, если регулярное выражение является глобальной.

> "azb".match(/a(z)b/);
[ "azb", "z" ]

> "azb".match(/a(z)b/g);
[ "azb" ]
>

другое дело, что если вы используете exec, обратите внимание, что это называется регулярным выражением, То если вы использовали переменную для регулярного выражения, у вас больше мощности

вы не получаете совпадений, когда вы не используете переменную для регулярного выражения, поэтому используйте переменную для регулярного выражения при использовании exec

> /./g.exec("abc")
[ "a" ]
> /./g.exec("abc")
[ "a" ]
> /./g.exec("abc")
[ "a" ]
>
> /[a-c]/g.exec("abc")
[ "a" ]
> /[a-c]/g.exec("abc")
[ "a" ]
>

> var r=/[a-c]/g
> r.exec("abc")
[ "a" ]
> r.exec("abc")
[ "b" ]
> r.exec("abc")
[ "c" ]
> r.exec("abc")
null
>

и с exec, вы можете получить "индекс" матча

> var r=/T/g
> r.exec("qTqqqTqqTq");
[ "T" ]
> r.lastIndex
2
> r.exec("qTqqqTqqTq");
[ "T" ]
> r.lastIndex
6
> r.exec("qTqqqTqqTq");
[ "T" ]
> r.lastIndex
9
> r.exec("qTqqqTqqTq");
null
> r.lastIndex
0
>

Так что если вы хотите индексы или захвата, а затем использовать метод exec (имейте в виду, что, как вы можете видеть, с "индексом", "индекс", который он дает, действительно является N-м случаем, он отсчитывается от 1. Таким образом, вы можете получить правильный индекс, вычитая 1. И как вы можете видеть, это дает 0-lastIndex 0-for not found).

и если вы хотите растянуть матч, вы можете использовать его при захвате, но не тогда, когда регулярное выражение является глобальным, и когда вы делаете это для этого, то содержимое массива не все совпадения, но полное совпадение, за которым следуют захваты.

The .match () функции str.match(regexp) следующее:

  • если есть и матч он вернется:
    • если g флаг и используется в регулярном выражении: он вернет все подстроки (игнорируя групп захвата)
    • если g флаг не используется в регулярном выражении: он будет возвращать то же самое, что и regexp.exec(str)
  • если есть нет матч он вернется:
    • null

примеры .match () С помощью g флаг:

var str = "qqqABApppabacccaba";
var e1, e2, e3, e4, e5;
e1 = str.match(/nop/g); //null
e2 = str.match(/no(p)/g); //null
e3 = str.match(/aba/g); //["aba", "aba"]
e4 = str.match(/aba/gi); //["ABA", "aba", "aba"]
e5 = str.match(/(ab)a/g); //["aba", "aba"] ignoring capture groups as it is using the g flag

и .match () без g флаг эквивалентно .exec ():

e1=JSON.stringify(str.match(/nop/))===JSON.stringify(/nop/.exec(str)); //true
//e2 ... e4 //true
e5=JSON.stringify(str.match(/(ab)a/))===JSON.stringify(/(ab)a/.exec(str)); //true

The .exec () функции regexp.exec(str) следующее:

  • если есть и матч будет возвращаться:
    • если g флаг и используется в регулярном выражении: он вернется (за каждый раз, когда он вызывается):[N_MatchedStr, N_Captured1, N_Captured2, ...] следующей N матч. важно: он не будет переходить в следующий матч, если объект regexp не хранится в переменной (это должен быть тот же объект)
    • если g флаг не используется в регулярном выражении: он будет возвращать то же самое, как если бы он имел g флаг и призвали к в первый раз и только один раз.
  • если есть нет матч он вернется:
    • null

пример .exec () (сохраненное регулярное выражение + с помощью g флаг = он меняется с каждым вызовом):

var str = "qqqABApppabacccaba";
var myexec, rgxp = /(ab)a/gi;

myexec = rgxp.exec(str);
console.log(myexec); //["ABA", "AB"]
myexec = rgxp.exec(str);
console.log(myexec); //["aba", "ab"]
myexec = rgxp.exec(str);
console.log(myexec); //["aba", "ab"]
myexec = rgxp.exec(str);
console.log(myexec); //null

//But in this case you should use a loop:
var mtch, myRe = /(ab)a/gi;
while(mtch = myRe.exec(str)){ //infinite looping with direct regexps: /(ab)a/gi.exec()
    console.log("elm: "+mtch[0]+" all: "+mtch+" indx: "+myRe.lastIndex);
    //1st iteration = elm: "ABA" all: ["ABA", "AB"] indx: 6
    //2nd iteration = elm: "aba" all: ["aba", "ab"] indx: 12
    //3rd iteration = elm: "aba" all: ["aba", "ab"] indx: 18
}

примеры .exec (), когда он не меняется с каждым вызовом:

var str = "qqqABApppabacccaba", myexec, myexec2;

//doesn't go into the next one because no g flag
var rgxp = /(a)(ba)/;
myexec = rgxp.exec(str);
console.log(myexec); //["aba", "a", "ba"]
myexec = rgxp.exec(str);
console.log(myexec); //["aba", "a", "ba"]
//... ["aba", "a", "ba"]

//doesn't go into the next one because direct regexp
myexec2 = /(ab)a/gi.exec(str);
console.log(myexec2); //["ABA", "AB"]
myexec2 = /(ab)a/gi.exec(str);
console.log(myexec2); //["ABA", "AB"]
//... ["ABA", "AB"]

Comments

    Ничего не найдено.