Seite 1 von 1

QStringList & QRegExp

Verfasst: 30. Januar 2019 12:43
von Meikelneit
Schönen guten Tag,

ich möchte gerne aus einem Qstring eine ganz bestimmte Passage uslesen und in eine andere Varible weiter geben. Ich habe aber im Moment keine Idee wie ich diese isolieren kann. Der Text sieht wie folgt aus:

DATA_BLOCK "Test"

Das zwischen den Anführungszeichen möchte ich extrahieren.
Im Moment komme ich mit der Regularexpression noch nicht so gut zurecht. Ich kann ein Einzelnes Anführungszeichen irgendwie nicht als Zeichen für einen Split angeben.

Code: Alles auswählen

 QRegExp exp_1("\\""); 
wird auf jeden fall nicht akzeptiert.

Wenn ich versuche jede Zeile einfach Zeichenweise auszulesen, kann ich auch in if Bedingungen keinen Zeichenvergleich auf das Anführungszeichen machen, so das ich in einer Forschleife somit auch die Zeichen zwischen den Anführungszeichen nicht auslesen kann. Wäre wahrscheinlich auch nicht adequat diese Lösung.

Kann mir jemand einen Ansatz bzw. eine Idee geben wie ich das Problem Lösen könnte?

PS: Am liebsten wäre mir eine RegularExpression die mir die Zeichenkette in Blöcke unterteilt welche durch das einfache " getrennt sind. Bekomme ich aber nicht richtig Konfiguriert.

Re: QStringList & QRegExp

Verfasst: 30. Januar 2019 13:16
von Christian81
Ich verstehe nicht warum man hier eine RegExp braucht - können in den Anführungszeichen Zeilenumbrüche sein? Wie sind im String Anführungszeichen kodiert?

Re: QStringList & QRegExp

Verfasst: 30. Januar 2019 13:22
von Meikelneit
Nein ich lese Zeiler für Zeile aus. Habs jetzt auch erstmal mit einer RegularExpression hinbekommen.
QRegExp exp_1("\""); funktioniert.

Re: QStringList & QRegExp

Verfasst: 30. Januar 2019 13:43
von Christian81
Also zum einen ist QRegExp deprecated (es sollte QRegularExpression verwendet werden) und zum anderen ist das wie mit Kanonen auf Spatzen zu schießen.

Code: Alles auswählen

while (file.canReadLine())
{
  const QString str = QString::fromUtf8(file.readLine())
  const int start = str.indexOf('"');
  const int end = str.lastIndexOf('"');
  if (start == end || start < 0)
    continue;
  const QString text = str.mid(start + 1, end - start - 1);
}

Re: QStringList & QRegExp

Verfasst: 30. Januar 2019 15:03
von Meikelneit
Nochmal herzlichen dank. Ich benutze den QRegularExpression an diesem einfachen Beispiel nur, weil die File die ich auswerte wesentlich Komplexer ist und ich verschiedene Segmente rausfiltern möchte. Ich möchte mir mehr oder weniger aus einem exportierten Datenbaustein einer SPS die Datenstruktur in eine Tabelle übernehmen. Um die Namen und Variablentypen richtig zuzuordnen möchte ich den RegularExpressions nehmen. Aber ich lasse mir auch da gerne Bessere Vorschläge machen.

Meine Testfile sieht folgender maßen aus:

DATA_BLOCK "Test"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
NON_RETAIN
VAR
Variable_1 : Bool;
Variable_2 : Bool;
Variable_3 : Bool;
Struct_1 : Struct
Struct_Element_1 : Bool;
Struct_Element_2 : Bool;
Struct_Element_3 : Bool;
Struct_Element_4 : Bool;
END_STRUCT;
END_VAR


BEGIN

END_DATA_BLOCK

Ich brauche den Namen, ob der Stein optimiert ist oder nicht, und ich möchte in ein Baumdiagramm alle Variablen samt der Unterstrukturen abbilden aka. struct und UDT bis zu einer Tiefe von 2.
Da mache ich jetzt einen Hybriden deines Vorschlags.

PS: Mir ist aufgefallen das du auch schon die ein oder andere Belehrung bezüglich des readLine gegeben hast. Vielleicht kannst du mir den auch mal kurz erklären. Zunächst dachte ich das man in dem readline die Zeilennummer übergeben kann, aus der gelesen werden soll. Das scheint aber eher so zu sein, das die Anzahl an Bytes mitgeteilt wird die er aus der Zeile liest. Soweit korrekt?

Des weiteren verstehe ich noch nicht genau wie sich die Funktion aber dennoch durch jede Zeile in der File hangelt, es wirkt so als würde sie sich jedes mal wenn sie ausgeführt wird, einen Pointer auf die nächste Zeile legen, und dann beim nächsten Aufruf diese auslesen usw.

PSS: Wenn der Code fertig ist Poste ich ihn mal hier. Könnte mir vorstellen das sich da noch was verbessern ließe.

Re: QStringList & QRegExp

Verfasst: 30. Januar 2019 15:19
von Christian81
QFile::readLine() lies die Zeichen aus der Datei bis zum nächsten \n (bzw. \r\n). D.h. der 'Lesepointer' wird weiter gesetzt. Ist aber bei allen (auch low-level) lesefunktionen so dass es einen filepointer gibt der auf die aktuelle Stelle in einer Datei zeigt.

Re: QStringList & QRegExp

Verfasst: 31. Januar 2019 11:03
von Meikelneit
So ich habe jetzt einen Code fertig der mir erstmal das gewünschte liefert, mit Berücksichtigung der Navigationstiefe. Aber ich bin überhaupt nicht von der Art der Lösung überzeugt. Ich würde es aber sehr begrüßen wenn mir jemand einen Ansatz formulieren kann, mit dem ich das Kompakter gelöst bekomme.
Ich fürchte ich bin im Moment im Tunnel und sehe Alternativlösungen nicht mehr.

Code: Alles auswählen

{
    QFileDialog dialog;
    dialog.setNameFilter(tr("*db (*db)"));
    dialog.setDirectory("C:\\Programmieren\\_projects\\Mirko-Test");

    if (dialog.exec())
    {
        if(dialog.selectedFiles().count()==0)
        {

        }
       else
        {
            QRegularExpression exp_1("\""), exp_2("\'"), exp_3(":");
            QString text, l_Variable, l_datentyp;
            QStringList l_List;
            int l_ZeilenNr = 1, l_Tiefe = 1;
            bool l_VARTABLE = false;
            QFile file(dialog.selectedFiles().at(0));

            line_Edit1->setText(dialog.selectedFiles().at(0));
            file.open(QIODevice::ReadOnly | QIODevice::Text);
            text_Edit1->setText(file.readAll());
            file.seek(0);
            text = file.readLine();

            while(file.canReadLine())
            {
    //Variablentabelle Anfang ermitteln
                if(text.trimmed() == "VAR")
                {
                    l_VARTABLE = true;
                    text = file.readLine();
                }
    //Variablentabelle Ende ermitteln
                if(text.trimmed() == "END_VAR")
                {
                    l_VARTABLE = false;
                }
    //Zeile 1 auswerten, DB_Name
                if(l_ZeilenNr == 1)
                {
                    l_List = text.split(exp_1);
                    qDebug().noquote()<<l_List.at(1);
                }
    //Zeile2 auswerten, DB_Optimiert(true,false)
                if(l_ZeilenNr == 2)
                {
                    l_List = text.split(exp_2);
                    qDebug().noquote()<<l_List.at(1);
                }
                if(l_ZeilenNr > 2)
                {
    //Variablentabelle Auswerten
                    if(l_VARTABLE)
                    {
                        l_List = text.split(exp_3);
                        if(text.trimmed() == "END_STRUCT;")
                        {
                            l_Tiefe = l_Tiefe - 1;
                        }
                        else
                        {
                            l_Variable = l_List.at(0).trimmed();
                            l_datentyp = l_List.at(1).trimmed();
                            qDebug().noquote()<<l_Variable<<l_datentyp<<l_Tiefe;
                            if(l_List.at(1).trimmed() == "Struct")
                            {
                                l_Tiefe = l_Tiefe + 1;
                            }

                        }
                    }
                }
                l_ZeilenNr = l_ZeilenNr + 1;
                text = file.readLine();
            }
            file.close();
        }
   }
}
[\Code]