Help with regular expression

Asked

Viewed 72 times

1

Hi, I need a hand with Regex. I need to split a string to store in a list, so I’m doing like this.

QString a = "strength 0.5";
QString b = "'kernels[1].params.sigma_albedo' 0.02";
QString c = "debugPixel '[336, 209]'";

QStringList myListA = a.split(QRegularExpression("\\s+"));
QStringList myListB = b.split(QRegularExpression("\\s+"));
QStringList myListC = c.split(QRegularExpression("\\s+"));

I need to separate by whitespace, but soon I will separate the parameter '[336, 209]' into two parts and I need them to be together: I even managed to do the following Regex ( '[ d+, s d+] ') but it is not right. I really need to select all the whitespace except the whitespace inside []. Does anyone know how to do that? I know I can do with loops and tests in the string, but I want to solve with Regex and also to understand better how it works.

myListA:
myList.at(0); // strength
myList.at(1); // 0.5

myListB:
myList.at(0); // 'kernels[1].params.sigma_albedo'
myList.at(1); // 0.2

// Errado
myListC: 
myList.at(0); // debugPixel
myList.at(1); // '[336,
myList.at(2); // 209]'

// Certo
myListC: 
myList.at(0); // debugPixel
myList.at(1); // '[336, 209]'
  • It seems to me that you are treating it in reverse. If your interest is to get the numerical values inside the brackets, why don’t you do the matching in each group of brackets and only then separates by the blank?

  • Hi Luiz Vieira, do you have an example to show me? I’m trying to do using a site to help in real time, but I haven’t quite figured it out yet http://regexr.com

1 answer

1


What I meant in the comments is that if you want to separate the numerical values between brackets, you should look directly for them instead of separating first by spaces and then separating the numerical values.

Anyway, answering what you asked, if you want to separate everything by spaces, but ignoring when the space is inside square brackets, a solution is the code below. The function teste1 does what you request. It uses a resource called "Lookahead" negative to check whether there is no the character ']' the front (is the part (?!\\d+]) at the end of the regular expression). If it exists, the regular expression does not match. Actually this is only a partial solution, to give you an idea of how it works, since she only looks if she has a bracket in front (and there are no brackets in the back and the front). The problem is that the lookbehind does not allow using regular subexpressions, so it is difficult to do it this way.

Already the function teste2 shows how you search exactly for comma-separated digits that are inside brackets (there yes, necessarily with an opening and a closing), and ignores the brackets (in ER "[^[]\\d+,\\s*\\d+[^]]", the parties [^[] and [^]] do that - ^ is the symbol for negation when used inside brackets). Then just make the separation (split) considering not only the space, but also the comma (is what the ER ",\\s*" ago).

#include <iostream>

#include <QString>
#include <QStringList>
#include <QRegularExpression>

using namespace std;

void teste1(const QString &a, const QString &b, const QString &c)
{
    QRegularExpression exp = QRegularExpression("\\s+(?!\\d+])");

    QStringList myListA = a.split(exp);
    QStringList myListB = b.split(exp);
    QStringList myListC = c.split(exp);

    cout << "myListA:" << endl;
    foreach(QString l, myListA)
        cout << "   " << l.toStdString() << endl;

    cout << "myListB:" << endl;
    foreach(QString l, myListB)
        cout << "   " << l.toStdString() << endl;

    cout << "myListC:" << endl;
    foreach(QString l, myListC)
        cout << "   " << l.toStdString() << endl;
}

void teste2(const QString &a, const QString &b, const QString &c)
{
    QRegularExpression exp = QRegularExpression("[^[]\\d+,\\s*\\d+[^]]");

    QStringList myListA = exp.match(a).capturedTexts();
    QStringList myListB = exp.match(b).capturedTexts();
    QStringList myListC = exp.match(c).capturedTexts();

    cout << "myListA:" << endl;
    foreach(QString l, myListA)
        if(!l.isEmpty())
        {
            QStringList values = l.split(QRegularExpression(",\\s*"));
            cout << "| ";
            foreach(QString v, values)
                cout << v.toStdString() << " | ";
            cout << endl;
        }

    cout << "myListB:" << endl;
    foreach(QString l, myListB)
        if(!l.isEmpty())
        {
            QStringList values = l.split(QRegularExpression(",\\s*"));
            cout << "| ";
            foreach(QString v, values)
                cout << v.toStdString() << " | ";
            cout << endl;
        }

    cout << "myListC:" << endl;
    foreach(QString l, myListC)
        if(!l.isEmpty())
        {
            QStringList values = l.split(QRegularExpression(",\\s*"));
            cout << "| ";
            foreach(QString v, values)
                cout << v.toStdString() << " | ";
            cout << endl;
        }
}

int main()
{
    QString a = "strength 0.5";
    QString b = "'kernels[1].params.sigma_albedo' 0.02";
    QString c = "debugPixel '[336, 209]'";

    cout << "TESTE 1 -------------------" << endl;
    teste1(a, b, c);

    cout << endl;

    cout << "TESTE 2 -------------------" << endl;
    teste2(a, b, c);

    return 0;
}

Upshot:

TESTE 1 -------------------
myListA:
   strength
   0.5
myListB:
   'kernels[1].params.sigma_albedo'
   0.02
myListC:
   debugPixel
   '[336, 209]'

TESTE 2 -------------------
myListA:
myListB:
myListC:
| 336 | 209 |
  • 1

    Thank you very much, this is exactly what I needed. I even made a very similar one, but without the ?! I will read again about these two characters to try to understand better. " s+(?! d+])"

Browser other questions tagged

You are not signed in. Login or sign up in order to post.