Search code examples
regexqtqregexp

QRegexp and percent (%) sign


I'm trying to match string of the form %foo% in a template. Context: The Goal is to replace %foo% by the value of the column foo in a stored procedure return.

I can't make it work. a the Beginning I tought the UTF8 encoding of my templates were the roots of my troubles. But even the below does fail:

#include <QCoreApplication>
#include <QRegExp>
#include <iostream>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QString str = "__%foo%____";


    std::cout << "with regex: %(.*)%" << std::endl;
    QRegExp re("%(.*)%",Qt::CaseInsensitive);
    re.indexIn(str);
    for(int pos = 0; pos < re.captureCount(); ++pos)
    {
        std::cout << re.cap(pos).toStdString() << std::endl;
    }

    std::cout << "with regex: \\%(.*)\\%" << std::endl;
    QRegExp re2("\\%(.*)\\%",Qt::CaseInsensitive);
    re2.indexIn(str);
    for(int pos = 0; pos < re2.captureCount(); ++pos)
    {
        std::cout << re2.cap(pos).toStdString() << std::endl;
    }

    std::cout << "with regex: %([^%])%" << std::endl;
    QRegExp re3("%([^%])%",Qt::CaseInsensitive);
    re3.indexIn(str);
    for(int pos = 0; pos < re3.captureCount(); ++pos)
    {
        std::cout << re3.cap(pos).toStdString() << std::endl;
    }

    std::cout << "with regex:  \\%([^\\%])\\%" << std::endl;
    QRegExp re4("\\%([^\\%])\\%",Qt::CaseInsensitive);
    re4.indexIn(str);
    for(int pos = 0; pos < re4.captureCount(); ++pos)
    {
        std::cout << re4.cap(pos).toStdString() << std::endl;
    }

    std::cout << "with regex: \\x25([^\\x25])\\x25" << std::endl;
    QRegExp re5("\\x25([^\\x25])\\x25",Qt::CaseInsensitive);
    re5.indexIn(str);
    for(int pos = 0; pos < re5.captureCount(); ++pos)
    {
        std::cout << re5.cap(pos).toStdString() << std::endl;
    }

    std::cout << "with regex: \\%(.*)\\%" << std::endl;
    QRegExp re6("\\%(.*)\\%",Qt::CaseInsensitive);
    re6.indexIn(str);
    for(int pos = 0; pos < re6.captureCount(); ++pos)
    {
        std::cout << re6.cap(pos).toStdString() << std::endl;
    }

    return a.exec();
}

Output:

with regex: %(.*)%
%foo%
with regex: \%(.*)\%
%foo%
with regex: %([^%])%

with regex:  \%([^\%])\%

with regex: \x25([^\x25])\x25

with regex: \%(.*)\%
%foo%

I only want to capture foo, not the '%'


Solution

  • ok puting each and every

    int pos = 0; pos < re.captureCount(); ++pos
    

    as

    int pos = 0; pos <= re.captureCount(); ++pos
    

    I have the output:

    with regex: %(.*)%
    %foo%
    foo
    with regex: \%(.*)\%
    %foo%
    foo
    with regex: %([^%])%
    
    
    with regex:  \%([^\%])\%
    
    
    with regex: \x25([^\x25])\x25
    
    
    with regex: \%(.*)\%
    %foo%
    foo
    

    The cap(0) matches the whole expression apparently