Требуется объяснение синтаксического анализа параметра запроса регулярного выражения Javascript

Сначала примеры, потом вопросы...

Пример 1) Неглобальное совпадение '?sort=alpha&direction=asc'

'?sort=alpha&direction=asc'.match(/([^?&=]+)(=([^&]*))?/);

Выход:

// ['sort=alpha', 'sort', '=alpha', 'alpha']

Пример 2) Глобальное совпадение '?sort=alpha&direction=asc'

'?sort=alpha&direction=asc'.match(/([^?&=]+)(=([^&]*))?/g);

Выход:

// ['sort=alpha', 'sort', '=alpha', 'alpha']

Пример 3) Замена глобального соответствия '?sort=alpha&direction=asc'

getRequestParameters: function () {
    var query_string = {},
        regex = new RegExp('([^?=&]+)(=([^&]*))?', 'g');

    '?sort=alpha&direction=asc'.replace(regex, function(match, p1, p2, p3, offset, string) {
        console.log(match, p1, p2, p3, offset, string);

        query_string[p1] = p3;
    });
}

Выход:

// sort=alpha sort =alpha alpha 1 ?sort=alpha&direction=asc
// direction=asc direction =asc asc 12 ?sort=alpha&direction=asc 


Мои вопросы

Я не уверен, что смог бы когда-нибудь додуматься до этого самостоятельно, но я никогда не «живу» с решением, и я должен понять рифму, стоящую за причиной. Конкретные совпадения я думаю понимаю "достаточно полностью". Я считаю, что знаю некоторые ответы ниже, но я предпочитаю не делать предположений и учиться у более умных людей!

  1. Почему 1) и 2) одинаковы? (или они?)
  2. Что означает sort=alpha в 1) и 2)?
  3. Почему 2) не возвращает параметры сортировки и направления?
  4. Что такое 3) перебор с .replace()?
  5. Есть ли способ захвата N параметров без .replace()?

Спасибо!

обновить

var regex = new RegExp('([^?&=]+)(=([^&]*))?');
regex.exec('?sort=alpha&direction=asc');
// Chrome 21 - ["sort=alpha", "sort", "=alpha", "alpha"]

var regex = new RegExp('([^?&=]+)(=([^&]*))?', 'g');
regex.exec('?sort=alpha&direction=asc');
// Chrome 21 - ["sort=alpha", "sort", "=alpha", "alpha"]

'?sort=alpha&direction=asc'.match(/([^?&=]+)(=([^&]*))?/);
// Chrome 21 - ["sort=alpha", "sort", "=alpha", "alpha"]

'?sort=alpha&direction=asc'.match(/([^?&=]+)(=([^&]*))?/g);
// Chrome 21 - ["sort=alpha", "direction=asc"]

var regex = new RegExp('([^?&=]+)(=([^&]*))?', 'g');
regex.lastIndex = 11;
regex.exec('?sort=alpha&direction=asc');
// Chrome 21 - ["direction=asc", "direction", "=asc", "asc"]

Таким образом, пример 3) по-прежнему верен, но перейдите к этот ответ для более квалифицированного ответа.

завершить обновление

Ссылки и благодарность Стивену Беннеру:


person chemoish    schedule 23.08.2012    source источник


Ответы (1)


Сначала ответы, потом вопросы:

  1. И в Chrome 21, и в Firefox 14 я получаю ["sort=alpha", "direction=asc"] для версии g, так что они совсем не совпадают.
  2. Первым возвращаемым значением из match является вся совпадающая строка (в данном случае один или несколько символов, которые не являются амперсандом, вопросительным знаком или знаком равенства, за которыми может следовать знак равенства и ноль или более символов, которые не являются амперсандом).
  3. Да (см. ответ на № 1) - в каком браузере вы запускаете эти тесты?
  4. replace перебирает каждое совпадение, найденное в строке.
  5. Используйте несколько вызовов exec или используйте существующее регулярное выражение:

    > '?sort=alpha&direction=asc&another=value'.match(/([^?&=]+)(=([^&]*))?/g);
    ["sort=alpha", "direction=asc", "another=value"]
    

Какой браузер вы используете, который дал вам результаты, которые вы указали на свои первые вопросы?

person Sean Vieira    schedule 23.08.2012
comment
Сохраните литерал регулярного выражения в var, затем вы также можете вызвать while (reg.exec(str)) для итерации. Поведение, которое вы представили, точно такое же, как описано в OP документация. - person Fabrício Matté; 23.08.2012
comment
@SeanVieira 1) Я получаю ваши результаты дома в Chrome 21 и Firefox 12. 2) Хотел убедиться. 3) Я узнаю версии браузера, когда пойду на работу (Первоначально размещено в Google Chrome). 4) Имеет гораздо больше смысла (я не думаю, что в противном случае задал бы этот вопрос) в контексте ['sort=alpha', 'direction=asc'] // сводки полного набора результатов (все еще немного сбивает с толку , лучше бы полностью зафиксировать результаты) 5) См. номер 4. - person chemoish; 23.08.2012
comment
@FabrícioMatté Не следуя инструкции while и вашей ссылке на документацию OP. Вы имеете в виду, что он будет повторять цикл дважды? - person chemoish; 23.08.2012
comment
@SeanVieira может быть быстрым регулярным выражением браузера - либо показывать сводку результатов, либо полное совпадение только первого совпадения ... придется провести еще несколько исследований! - person chemoish; 23.08.2012
comment
@chemoish Мой комментарий был основан на вашем 5-м вопросе (альтернатива для замены). Проверьте этот ответ для более подробной информации. - person Fabrício Matté; 23.08.2012
comment
@chemoish - match должен вести себя таким образом - он следует тем же правилам, что и exec (когда флаг g не указан, он дает вам каждую группу захвата; когда он указан, он просто дает вам каждое совпадение ). - person Sean Vieira; 23.08.2012
comment
@FabrícioMatté Спасибо, ответ, представленный в вашем комментарии, резюмировал почти все. Я бы хотел, чтобы раздел комментариев был лучше, поэтому я добавлю свои окончательные выводы к своему исходному сообщению. - person chemoish; 23.08.2012