====== Regular Expressions (Reguläre Ausdrücke) ====== [[regex:start|Regular Expressions]] sind aus Programmiersprachen wie Python oder Perl nicht wegzudenken. Da ihre direkte Verwendung in C++ nicht möglich ist, bietet Qt dafür eine Lösung.\\ Die Klasse ''QRegExp'' bietet eine objektorientierte Schnittstelle zur Verwendung von regulären Ausdrücken. Sie wird über folgenden Konstruktor instanziert: QRegExp( const QString& pattern, Qt::CaseSensitivity cs = Qt::CaseSensitive, PatternSyntax syntax = RegExp ) **pattern**: Der eigentliche reguläre Ausdruck.\\ **cs**: Gibt an, ob der reguläre Ausdruck Groß-/Kleinschreibung berücksichtigt oder nicht.\\ **syntax**: Auswahl aus verschiedenen Syntaxen.\\ \\ Praktischerweise gibt es auch eine Methode ''isValid()'' um zu prüfen, ob der angegebene Ausdruck gültig ist. Eine Fehlermeldung kann dabei über ''errorString()'' abgefragt werden. \\ Der Backslash, der fester Bestandteil des von regular Expressions ist, muss natürlich nach den C++-Regeln doppelt hintereinander vorkommen um einen gültigen Backslash im String zu erhalten.\\ Quantoren sind wie in Perl standardmäßig "gierig", d.h. sie versuchen so viele Zeichen wie möglich in Anspruch zu nehmen. Das gebräuchliche Fragezeichen nach einem Quantor funktioniert in Qt nicht, sondern es muss die Methode ''setMinimal()'' mit ''true'' als Parameter aufgerufen werden.\\ ===== Übereinstimmung ===== Zur Prüfung eines Strings auf Übereinstimmung mit dem regulären Ausdruck wird ''indexIn()'' verwendet. int indexIn( const QString& str, int offset = 0, CaretMode caretMode = CaretAtZero ) const **str**: String der auf Übereinstimmung geprüft werden soll.\\ **offset**: Offset vom Beginn des übergebenen Strings.\\ **caretMode**: Gibt an, an welcher Position ''^'' zutrifft, standardmäßig ist das der Beginn des Strings.\\ **Rückgabewert**: Index der Übereinstimmung, -1 wenn es keine Übereinstimmung gibt.\\ \\ Die Methode ''captureTexts()'' gibt eine ''QStringList''-Instanz zurück, die als erstes Element den gesamten String und die weiteren Gruppen enthält.\\ \\ Das folgende Beispiel gibt die einzelnen Teile einer URL aus: #include #include #include int main() { QString str( "https://proggen.org/" ); QRegExp regex( "(\\w+)://(\\w+)\\.(\\w+)/" ); regex.indexIn( str ); QStringList matches = regex.capturedTexts(); for( int i = 1; i < matches.size(); i++ ) std::cout << "match " << (int) i << ": " << matches[i].toStdString() << std::endl; return 0; } Ausgabe: match 1: https match 2: proggen match 3: org ===== Ersetzung ===== Wir können reguläre Ausdrücke auch zur Ersetzung von Texten in ''QString''-Objekten verwenden. Die Methode liegt diesmal aber nicht in ''QRegExp'', sondern direkt in ''QString''. QString& replace( const QRegExp& rx, const QString& after ) **rx**: Regulärer Ausdruck, der zum Vergleich verwendet wird.\\ **after**: Text, durch den der reguläre Ausdruck ersetzt wird.\\ **Rückgabewert**: Der neue String, in dem der reguläre Ausdruck durch den zweiten Parameter ersetzt wurde.\\ \\ Wir können im String **after** auch Rück-Referenzen auf den regulären Ausdruck (\1, \2, ..; bzw. \\1, \\2, ... nach C++-Syntax) verwenden. \\ Im nächsten Beispiel löschen wir alle HTML-Tags aus einem String: #include #include #include int main() { QString str( "

proggen.org

" ); QRegExp regex( "<.+>" ); regex.setMinimal( true ); std::cout << str.replace( regex, "" ).toStdString() << std::endl; return 0; }
Ausgabe: proggen.org \\ So, nun wollen wir auch von Rück-Referenzen Gebrauch machen. Wir nehmen an wir haben Daten über Personen nach folgendem Format: VornamePerson1,NachnamePerson1 VornamePerson2,NachnamePerson2 ... Wir hätten das jedoch gern umgekehrt und mit einem Semikolon als Trennzeichen, nämlich: NachnamePerson1;VornamePerson1 NachnamePerson2;VornamePerson2 ... Nun zum Programm (der Einfachheit halber sind die Namen statisch festgelegt): #include #include #include int main() { QString str( "Anton,Ansbach\n"\ "Frank,Ferdinand\n"\ "Karl,Klaasen\n"\ "Otto,Ottendorf\n"\ "Walter,Wurz\n"\ "Zelda,Zett\n" ); QRegExp regex( "(.+),(.+)\n" ); regex.setMinimal( true ); std::cout << str.replace( regex, "\\2;\\1\n" ).toStdString() << std::endl; return 0; } Ausgabe: Ansbach;Anton Ferdinand;Frank Klaasen;Karl Ottendorf;Otto Wurz;Walter Zett;Zelda