Regex - группа повторного захвата
Я пытаюсь выяснить, как я могу повторить группу захвата на comma-separated
Значения в этой следующей строке URL:
id=1,2;name=user1,user2,user3;city=Oakland,San Francisco,Seattle;zip=94553,94523;
Я использую это RegExp
который возвращает результаты, которые я хочу, за исключением значений, так как они являются динамическими, т.е. в параметре url может быть 2,3,4 и т.д. пользователей, и мне было интересно, могу ли я создать группу захвата для каждого значения вместо user1,user2,user3
как одна группа захвата.
RegExp: (^|;|:)(\w+)=([^;]+)*
Вот живая демонстрация этого онлайн, используя RegExp
Пример вывода:
- Группа1 - (точка с запятой, двоеточие)
- Group2 - (ключ т.е. идентификатор, имя, город, почтовый индекс)
- Группа3 - (значение1)
- Группа 4 - (значение 2) *, если существует
- Группа 5 - (значение 3) *, если существует
- Группа 6 - (значение 4) *, если существует
и т.д. на основе динамических значений, как я объяснил ранее.
Вопрос: Что не так с моим выражением? Я использую *
зацикливаться на повторяющихся узорах?
1 ответ
Regex не поддерживает то, что вы пытаетесь сделать. Когда двигатель входит в группу захвата во второй раз, он перезаписывает то, что он захватил в первый раз. Рассмотрим простой пример (спасибо регулярно-expressions.info): /(abc|123)+/
используется на 'abc123'
, Он будет соответствовать "abc", затем увидеть плюс и повторить попытку, соответствующий "123". Конечная группа захвата в выходных данных будет "123".
Это происходит независимо от того, какой шаблон вы используете, и любое установленное вами ограничение просто изменяется, когда регулярное выражение принимает строку. Рассматривать /(abc|123){2}/
, Это принимает "abc123" с группой захвата как "123", но не "abc123abc". Помещение группы захвата в другую тоже не работает. Когда вы создаете группу захвата, это похоже на создание переменной. Он может иметь только одно значение, а последующие значения перезаписывают предыдущее. Вы никогда не сможете иметь больше групп захвата, чем пары пар в скобках (хотя определенно вы можете иметь меньше).
Тогда возможное исправление состоит в том, чтобы разбить строку на ";", затем на каждую из них на "=", а затем на правую часть от ",". Это поможет вам [['id', '1', '2'], ['name', 'user1', ...], ['city', ...], ['zip', ...]]
,
Это выходит:
function (str) {
var afterSplit = str.split(';|:');
afterSplit.pop() // final semicolon creates empty string
for (var i = 0; i < afterSplit.length; i++) {
afterSplit[i] = afterSplit[i].split('=');
afterSplit[i][1] = afterSplit[i][1].split(','); // optionally, you can flatten the array from here to get something nicer
}
return afterSplit;
}
Группа захвата повторяется
Строка:! Abc123def! регулярное выражение: /!((abc|123|def)+)!/
Матчи:
Группа 1: abc123def
Группа 2: def
источник: https://www.regular-expressions.info/captureall.html