Сопоставьте вложенные группы захвата с квантификаторами, используя QRegularExpression - PullRequest
1 голос
/ 08 мая 2019

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

Я использую это регулярное выражение:

<[a-z]+(?: [a-z]+=("[^"]*"))*>

И я хотел бы получить «а» и «б» с этим текстом:

<p a="a" b="b">

Вот код:

const QString text { "<p a=\"a\" b=\"b\">" };
const QRegularExpression pattern { "<[a-z]+(?: [a-z]+=(\"[^\"]*\"))*>" };

QRegularExpressionMatchIterator it = pattern.globalMatch(text);
while (it.hasNext())
{
    const QRegularExpressionMatch match = it.next();

    qDebug() << "Match with" << match.lastCapturedIndex() + 1 << "captured groups";
    for (int i { 0 }; i <= match.lastCapturedIndex(); ++i)
        qDebug() << match.captured(i);
}

И вывод:

Match with 2 captured groups
"<p a=\"a\" b=\"b\">"
"\"b\""

Можно ли получить несколько групп захвата с помощью квантификатора * или я должен выполнить итерацию, используя QRegularExpressionMatchIterator с определенным регулярным выражением для строковых литералов?

1 Ответ

1 голос
/ 08 мая 2019

Это выражение может помочь вам просто захватить эти атрибуты, и оно не ограничено слева и справа:

([A-z]+)(=\x22)([A-z]+)(\x22)

enter image description here

Graph

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

enter image description here


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

(?:^<p )?([A-z]+)(=\x22)([A-z]+)(\x22)

Тест на RegEx

const regex = /(?:^<p )?([A-z]+)(=\x22)([A-z]+)(\x22)/gm;
const str = `<p attributeA="foo" attributeB="bar" attributeC="baz" attributeD="qux"></p>`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}
...