Я не могу точно понять, как работает метод sg флага JavaScript string.match(regexp)

В книге "JavaScript: хорошие части" он объясняет метод string.match(regexp) как показано ниже:

Метод match сопоставляет строку и регулярное выражение. Как это сделать, зависит от флага g. Если флаг g отсутствует, то результат вызова строки.match (regexp) будет таким же, как и вызов regexp.exec (string). Однако, если регулярное выражение имеет флаг g, то оно создает массив всех совпадений, но исключает группы захвата:

Затем в книге приведен пример кода:

var text = '<html><body bgcolor=linen><p>This is <b>bold<\/b>!<\/p><\/body><\/html>';
var tags = /[^<>]+|<(\/?)([A-Za-z]+)([^<>]*)>/g;
var a, i;
a = text.match(tags);
for (i = 0; i < a.length; i += 1) {
    document.writeln(('// [' + i + '] ' + a[i]).entityify());
}
// The result is
// [0] <html>
// [1] <body bgcolor=linen>
// [2] <p>
// [3] This is
// [4] <b>
// [5] bold
// [6] </b>
// [7] !
// [8] </p>
// [9] </body>
// [10] </html>

Мой вопрос в том, что я не могу понять, "но исключаю группы захвата".

В приведенном выше примере кода html в </html> находится в группе захвата. И почему он все еще включен в массив результатов?

А также / в </html> также в группе захвата. И почему он включен в массив результатов?

Не могли бы вы объяснить "но исключает группы захвата" приведенным выше примером кода?

Большое спасибо!

2 ответа

Решение

В приведенном выше примере кода html в находится в группе захвата. И почему он все еще включен в массив результатов?

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

// The result is
// [0] <html>
// [1]           // From the capture group; nothing here
// [2] html      // From the capture group
// [3]           // From the capture group; nothing here
// ...

И / в также находится в группе захвата. И почему он включен в массив результатов?

По той же причине, что и выше: это часть общего матча, и это то, что в результате; содержимое отдельных групп захвата не.

Это легче понять на более простом примере. Рассмотрим этот код:

var s = "test1 test2";
var re = /(test)(.)/g;
var r = s.match(re);
var i;
for (i = 0; i < r.length; ++i) {
    console.log("[" + i + "]: '" + r[i] + "'");
}

Потому что регулярное выражение имеет g флаг, только полные совпадения включены в массив, поэтому мы видим:

[0]: 'test1'
[1]: 'test2'

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

Если мы удалили g помечайте, но ничего не меняя, мы получим первое полное совпадение с последующим содержимым двух групп захвата:

[0]: 'test1' // Полное совпадение, включая данные из каждой группы захвата [1]: 'test'     // Содержимое группы 0 захвата [2]: '1'        // Содержимое группы 1

Там первая запись - полное совпадение; тогда второй и третий являются содержимым групп захвата. Обратите внимание, что содержимое группы захвата

g Модификатор должен применять регулярное выражение во всем мире. Без этого регулярное выражение сопоставляет и возвращает первое найденное совпадение. С его помощью он ищет и сопоставляет все вхождения в строке.

Другие вопросы по тегам