Подтвердить что ты не робот

Соответствие Vs exec в JavaScript

Мне нужно некоторое уточнение для соответствия Vs exec в JavaScript; здесь кто-то говорит, что

"exec с глобальным регулярным выражением предназначен для использования в цикле", но прежде всего, как вы видите в моем примере, это не так; в моем примере exec с глобальным регулярным выражением возвращает все совпадения в массиве! Во-вторых, они говорят, что для String.match он возвращает все совпадения без необходимости прокрутки! Но опять же, что не происходит в моем примере, и он просто возвращает строку ввода? Я неправильно понял/сделал что-то не так?

var myString = "[22].[44].[33].";
var myRegexp = /.*\[(\d*)*\].*\[(\d*)*\].*\[(\d*)*\].*/g;

var execResult = myRegexp.exec(myString);
console.log(execResult.length);
console.log(execResult[1]);// returns 22 and execResult has all of my matches from index 1 to the length of array


var matchResult = myString.match(myRegexp);
console.log(matchResult.length);
console.log(matchResult);// returns just myString which is "[22].[44].[33]."! Why is that?
4b9b3361

Ответ 1

  • string.match находит первое совпадение и возвращает его с фактическим совпадением, индекс, по которому был найден текст, и фактический ввод, когда глобальный флаг не используется.

  • string.match просто возвращает все совпадения, когда используется глобальный флаг.

    var myString = "[22].[44].[33].";
    
    console.log(myString.match(/\d+/));
    # [ '22', index: 1, input: '[22].[44].[33].' ]
    console.log(myString.match(/\d+/g));
    # [ '22', '44', '33' ]
    

Основное различие между string.match и regex.exec заключается в том, что объект regex будет обновлен в текущем совпадении с вызовом regex.exec. Например,

var myString = "[22].[44].[33].", myRegexp = /\d+/g, result;

while (result = myRegexp.exec(myString)) {
    console.log(result, myRegexp.lastIndex);
}

вернет

[ '22', index: 1, input: '[22].[44].[33].' ] 3
[ '44', index: 6, input: '[22].[44].[33].' ] 8
[ '33', index: 11, input: '[22].[44].[33].' ] 13

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

  • Если вы не используете параметр g, вы всегда получите первое совпадение, если оно есть, иначе null. Итак, следующее будет работать в бесконечном цикле.

    var myString = "[22].[44].[33].", myRegexp = /\d+/, result;
    
    while (result = myRegexp.exec(myString)) {
        console.log(result, myRegexp.lastIndex);
    }
    
  • Не забудьте использовать тот же объект регулярного выражения с последующими вызовами. Поскольку объект regex обновляется каждый раз, и если вы передаете новый объект, снова программа будет запущена в бесконечный цикл.

    var myString = "[22].[44].[33].", result;
    
    while (result = /\d+/g.exec(myString)) {
        console.log(result);
    }
    

Ответ 2

String.prototype.match() и RegExp.prototype.exec() одинаковы как при поиске нескольких вхождений, так и при их возврате в массив. И все же метод exec возвращает массив более подробной информации. Например, в отличие от совпадения, он также может найти несколько вхождений групп захвата. Так что если у вас есть группы захвата, exec необходим. При работе с exec следует помнить одну вещь, которую вы не должны вызывать из буквального регулярного выражения. Сначала присвойте свое регулярное выражение переменной и используйте его для вызова вашего метода exec. Другое дело, что в то время как сопоставление будет приводить к множеству вхождений в массиве элементов за один раз, с exec вы должны выполнять итерацию для каждого регистрируемого вхождения.

Вызов матча довольно прост. Так как это метод прототипа строки, вы просто связываете его со строкой и предоставляете регулярное выражение в качестве аргумента метода match подобно; "test".match(/es /) Буквальное представление регулярного выражения можно использовать без проблем.

Вызов exec более сложен. Как я упоминал ранее, лучше иметь регулярное выражение для чего-то ранее. Хорошо, давайте посмотрим на пример

var text = '["job name 1","nat 1"],["job name 2","nat 2"],["job name 3","nat 3"]',
     reg = /([^"]+)","([^"]+)/g,
      tm = [],
      te = [];

tm = text.match(reg); // tm has result of match
while(te[te.length]=reg.exec(text)); // te has result of exec + an extra null item at the end
te.length--; // te normalized.

document.write("<pre>" + JSON.stringify(tm,null,2) + "</pre>\n");
document.write("<pre>" + JSON.stringify(te,null,2) + "</pre>\n");