QRegExp для анализа только строки, начинающейся с определенного символа

Я пытаюсь проанализировать эти строки, используя регулярное выражение, но я думаю, что мое выражение регулярного выражения неверно.

Мне дана строка, и всякий раз, когда она имеет новую строку и возврат каретки, они должны быть разделены на две строки. Строки имеют следующий формат

[CharSize][Inverted][Aligned]Data

Например, если мне даны такие данные

QString s1 = "[6][1][0]Data1\n\r[5][0][1]Data2";

Когда я разделю их, будет две QString, и я возьму данные внутри открытых и закрытых скобок.

Другие действительные данные выглядят так:

QString s2 = "[7][0][1]Data3"

Неверные данные выглядят так:

QString s3 = "abc[8][1][1]Data4"

Я применил следующий QRegExp ниже:

QRegExp clrf("\n\r|\r\n|\n");
QStringList sp = str.split(clrf);

QRegexp clrf отлично работает для разделения данных с новой строкой и возвратом каретки, в обратном порядке или просто с новой строкой. Примечание: s1, s2 и s3 здесь обрабатываются нормально.

Проблема здесь:

QRegExp value("[^a-z]?\\[([0-9a-z]+)\\]\\[([0-9a-z]+)\\]\\[([0-9a-z]+)\\]([A-Za-z0-9\\'\\ \"]*)");

Когда я использую приведенный выше код, все s1, s2 и s3 обрабатываются. S3 НЕ ДОЛЖЕН обрабатываться, поскольку его первый символ не является открывающей скобкой. Можете ли вы помочь мне исправить мой QRegExp?

Спасибо.

РЕДАКТИРОВАТЬ: Весь код:

void parseString(QString str)
{

    QRegExp clrf("\n\r|\r\n|\n");
    QRegExp value("\\[([0-9a-z]+)\\]\\[([0-9a-z]+)\\]\\[([0-9a-z]+)\\]([A-Za-z0-9\\'\\ \"]*)");
//     QRegExp value("^\[(\\d+)\]\[(\\d+)\]\[(\\d+)\](.*)$");

    int p = 0, i = 0;
    int res;
    int cs = 0, inv = 0, al = 0;

    QStringList sp = str.split(clrf);

    XLineString ls;

    for (i = 0; i < sp.size(); ++i) {
        res = value.indexIn(sp[i], p);
        while (res != -1) {
            printf("Text=[%s]\n", value.cap(EData).toStdString().c_str());

            printf("Digit cs[%d] ", value.cap(ECharSize).toInt());
            printf("inv[%d] ", value.cap(EInvert).toInt());
            printf("al[%d]\n", value.cap(EAlignment).toInt());

            cs = value.cap(ECharSize).toInt();
            if (value.cap(EInvert).toInt())
                inv = 1;
            else
                inv = 0;

            if (value.cap(EAlignment).toInt())
                al = 1;
            else
                al = 0;
            ls.addLine(value.cap(EData).toStdString().c_str(), cs, inv, al);
            p += value.matchedLength();
            res = value.indexIn(str, p);
        }
    }    
}

int main()
{   
    QString str1[] = { 
        "[12][0][0]DATA1\n\r[78][0][1]DATA2",
        "abc[1][1][1]THIS SHOULD NOT PASS",
    };

    for (int i = 0; i < sizeof(str1) / sizeof(str1[0]); ++i)
        parseString(str1[i]);
}

person Gibs    schedule 16.11.2015    source источник
comment
Есть ли у вас причина явно указывать: [^a-z]?, почему бы просто не использовать начало строки: ^[[0-9]+]...' Наконец, я думаю, что ваше выражение можно довольно упростить с помощью \w и \д: '^\\[(\\d+)\\]\\[(\\d+)\\]\\[(\\d+)\\](.*)$'   -  person u8sand    schedule 16.11.2015
comment
Я использовал [^a-z]?, который предположительно должен игнорировать любые строки, содержащие символы, начинающиеся с не открытой скобки. Вы имеете в виду это? ^\\[([0-9a-z]+)\\].... Я попробовал этот, но s3 все еще ловится. Мне действительно жаль. Я не силен в регулярном выражении. Можете ли вы объяснить предложенное вами выражение в последней части?   -  person Gibs    schedule 16.11.2015
comment
Кстати, я только что попробовал QRegExp value("^\\[(\\d+)\\]\\[(\\d+)\\]\\[(\\d+)\\](.*)$");, и все еще ловится s3 :(   -  person Gibs    schedule 16.11.2015
comment
Что вы используете для самого сопоставления? Регулярное выражение правильное, это что-то другое.   -  person u8sand    schedule 16.11.2015
comment
Я отобразил выше весь свой код. Извините за беспокойство, которое я причинил.   -  person Gibs    schedule 16.11.2015


Ответы (1)


Чтобы ответить на ваш вопрос, я проверил это с помощью PyQt5 (для простоты)

import re
R = ["\\[([0-9a-z]+)\\]\\[([0-9a-z]+)\\]\\[([0-9a-z]+)\\]([A-Za-z0-9\\'\\ \"]*)", "^\[(\\d+)\]\[(\\d+)\]\[(\\d+)\](.*)$"]
tests = ["[6][1][0]Data1\n\r[5][0][1]Data2", "[7][0][1]Data3", "abc[8][1][1]Data4"]
s = re.compile("\n\r|\r\n|\n") # emulate QRegExp split feature
for r in R:
    r=QRegExp(r)
    for T in tests:
        for t in s.split(T):
            print(r.indexIn(t))

Результаты:

0
0
0
3
0
0
0
-1

Вывод: ваше исходное совпадение также может работать, если вы просто проверите, что «indexIn» равно 0, а не равно -1, в то время как моя модифицированная версия должна работать в любом случае.

Я думаю, что вам лучше всего просто изменить код, убедившись, что индекс равен 0. Я также могу предложить вам использовать оператор If, а не оператор While, иначе вы можете многократно сопоставлять одну и ту же строку.

person u8sand    schedule 16.11.2015
comment
мой плохой, я не проверял каждый блок своего кода -_- Большое спасибо u8sand :) - person Gibs; 16.11.2015