Прочитать разные строки QStrings с тем же предыдущим и тем же следующим словом?QString :: IndexOf - PullRequest
0 голосов
/ 09 марта 2012

Я читаю две строки QStrings (ValueOne, ValueTwo) из файла с (просто базовый пример)

int main(int argc, char *argv[]) {
    QString x = ("yes " 
                 "start ValueOne end" 
                 "no" 
                 "start ValueTwo end");

   //try to read ValueOne
    QString s = "start";
    QString e = "end";
    int start = x.indexOf(s, 0, Qt::CaseInsensitive); 
    int end = x.indexOf(e, Qt::CaseInsensitive); 

    if(start != -1){ 

        QString y = x.mid(start + s.length(), (end - (start + s.length()))); 

        qDebug() << y << (start + s.length()) << (end - (start + s.length()));

    //try to read ValueTwo
    QString s2 = "start";
    QString e2 = "end";
    int start2 = x.indexOf(s2, 0, Qt::CaseInsensitive); 
    int end2 = x.indexOf(e2, Qt::CaseInsensitive); 

    if(start2 != -1){ 

        QString y2 = x.mid(start2 + s.length2(), (end2 - (start2 + s.length2()))); 

        qDebug() << y2 << (start2 + s.length2()) << (end2 - (start2 + s.length2()));
    }
}

Как вы видите, исходный код не может отличить ValueOne от ValueTwo просто при запуске"и" конец ", потому что оба метода QString :: mid () (которые, насколько я знаю, выполняются построчно) имеют одинаковую начальную позицию и одинаковую длину (см. http://qt -project.org / doc/qt-4.8/qstring.html#mid).Поэтому я подумал, что если бы вся строка была одной строкой, как

QString x = "yes start ValueOne end no start ValueTwo end ";

, я мог бы отличить два значения с помощью QString s = "yes start" и QString s2 = "no start".Так будет ли преобразование многострочного String в однострочное String, и как я могу это сделать?или есть другое, может быть, лучшее решение?привет

Ответы [ 2 ]

2 голосов
/ 09 марта 2012

Как я уже упоминал в вашем другом вопросе, я бы предпочел QRegExp .Кажется, он более читабелен.

Если ваша первая строка всегда имеет значение 2n, а вторая строка 2n+1, вы можете использовать оператор по модулю:

#include <QDebug>
#include <QString>
#include <QStringList>
#include <QRegExp>

int main()
{
    QString x = ("yes \nstart ValueOne end \nno \nstart ValueTwo end\n"
                "yes \nstart ValueThree end \nno \nstart ValueFour end ");

    QStringList y1;
    QStringList y2;

    // create regular expression
    QRegExp rx("start\\s+(.+)\\s+end\\s+", Qt::CaseInsensitive);

    // don't try to get the largest match (start ValueOne ... ValueFour end)
    // minimal match should be (start ValueOne end)
    rx.setMinimal(true);

    int pos=0;
    int i=0; // counter

    // look for possible matches
    QString match;
    while ((pos=rx.indexIn(x, pos)) != -1) {
        i+=1; // increase counter for every match
        match=rx.cap(1); // get first match in (.+)

        // use modulo to distinguish between y1/y2    
        if (i % 2) {
            y1 << match;
        } else {
            y2 << match;
        }

        pos+=rx.matchedLength();
    }

    qDebug() << "y1:" << y1;
    qDebug() << "y2:" << y2;

    return 0;
}
1 голос
/ 09 марта 2012

С помощью чего-то похожего на код ниже вы можете найти все строки между «начало» и «конец».Поместите поиск «start» и «end» в цикл и используйте параметр смещения indexOf, чтобы продолжить поиск новых разделителей после первого.

int main(int argc, char *argv[]) {
    QString x = ("yes /nstart ValueOne end /nno /nstart ValueTwo end ");

    QString s = "start";
    QString e = "end";

    // Look for all the strings between "start" and "end"    
    for(int offset(0); offset < x.length(); )
    {
        // Search for "start" starts from offset
        int start = x.indexOf(s, offset, Qt::CaseInsensitive); 

        if(start < 0){
            break;
        }

        // Search for "end" starts from the position of "start"
        int end = x.indexOf(e, start, Qt::CaseInsensitive); 
        if(end < 0){
            break;
        }

        // Next search for "start" will start from the current position of "end"
        offset = end;

        QString y = x.mid(start + s.length(), (end - (start + s.length()))); 
        qDebug() << y << (start + s.length()) << (end - (start + s.length()));
    }
}
...