Boost.Regex ermöglicht es, reguläre Ausdrücke in C++ einzusetzen. Da die Bibliothek seit C++11 Teil der Standardbibliothek ist, sind Sie nicht auf Boost.Regex angewiesen, wenn Sie in einer Entwicklungsumgebung arbeiten, die C++11 unterstützt. Sie können auf die gleichnamigen Klassen und Funktionen im Namensraum std
zugreifen, wenn Sie die Headerdatei regex
einbinden.
Die wichtigsten Klassen in Boost.Regex sind boost::regex
und boost::smatch
, die beide in der Headerdatei boost/regex.hpp
definiert sind. Während boost::regex
verwendet wird, um einen regulären Ausdruck zu definieren, speichert boost::smatch
Suchergebnisse.
Im Folgenden lernen Sie die drei Funktionen kennen, die Boost.Regex zur Suche mit regulären Ausdrücken anbietet.
boost::regex_match()
vergleichen#include <boost/regex.hpp>
#include <string>
#include <iostream>
int main()
{
std::string s = "Boost Libraries";
boost::regex expr{"\\w+\\s\\w+"};
std::cout << std::boolalpha << boost::regex_match(s, expr) << '\n';
}
Die Funktion boost::regex_match()
, die im Beispiel 8.1 verwendet wird, vergleicht einen String in Gänze mit einem regulären Ausdruck. Die Funktion gibt true
zurück, wenn der reguläre Ausdruck auf den gesamten String passt.
Um einen String nach einem regulären Ausdruck zu durchsuchen, verwenden Sie boost::regex_search()
.
boost::regex_search()
durchsuchen#include <boost/regex.hpp>
#include <string>
#include <iostream>
int main()
{
std::string s = "Boost Libraries";
boost::regex expr{"(\\w+)\\s(\\w+)"};
boost::smatch what;
if (boost::regex_search(s, what, expr))
{
std::cout << what[0] << '\n';
std::cout << what[1] << "_" << what[2] << '\n';
}
}
Die Funktion boost::regex_search()
erwartet als zusätzlichen Parameter eine Referenz auf ein Objekt vom Typ boost::smatch
. In diesem Objekt speichert boost::regex_search()
die Ergebnisse. Dabei wird nur nach Gruppierungen gesucht. So werden im Beispiel 8.2 zwei Ergebnisse gespeichert, weil es zwei Gruppierungen im regulären Ausdruck gibt.
Die Klasse boost::smatch
, in der Suchergebnisse gespeichert werden, ist ein Container für Elemente vom Typ boost::sub_match
. Sie bietet eine ähnliche Schnittstelle wie std::vector
. So kann über operator[]
auf Elemente vom Typ boost::sub_match
zugegriffen werden.
boost::sub_match
speichert Iteratoren auf die Positionen in einem String, die einer Gruppierung in einem regulären Ausdruck entsprechen. Da boost::sub_match
von std::pair
abgeleitet ist, kann über first und second auf die Iteratoren zugegriffen werden, die einen Substring identifizieren. Wie im Beispiel 8.2 zu sehen, muss nicht auf diese Iteratoren zugegriffen werden, um einen Substring auf die Standardausgabe auszugeben. Da der Operator operator<<
für boost::sub_match
überladen ist, kann ein Substring direkt ausgegeben werden.
Beachten Sie, dass boost::sub_match
Iteratoren speichert. Ergebnisse werden nicht kopiert. Sie dürfen daher auf Iteratoren in Objekten vom Typ boost::sub_match
nur zugreifen, solange der String, auf den die Iteratoren zeigen, existiert.
Beachten Sie außerdem, dass das erste Element im Container boost::smatch
mit dem Index 0 Iteratoren speichert, die auf den String zeigen, der dem gesamten regulären Ausdruck entspricht. Der erste Substring, der der ersten Gruppierung entspricht, wird über den Index 1 angesprochen.
Die dritte Funktion, die Boost.Regex bietet, ist boost::regex_replace()
.
boost::regex_replace()
ersetzen#include <boost/regex.hpp>
#include <string>
#include <iostream>
int main()
{
std::string s = " Boost Libraries ";
boost::regex expr{"\\s"};
std::string fmt{"_"};
std::cout << boost::regex_replace(s, expr, fmt) << '\n';
}
Der Funktion boost::regex_replace()
muss neben dem zu durchsuchenden String und einem regulären Ausdruck ein Formatierungsstring übergeben werden. Der Formatierungsstring definiert, wie Substrings, die Gruppierungen im regulären Ausdruck entsprechen, ersetzt werden. Wenn der reguläre Ausdruck so wie im Beispiel 8.3 keine Gruppierungen enthält, werden entsprechende Substrings eins zu eins mit dem Formatierungsstring ersetzt. Beispiel 8.3 gibt als Ergebnis _Boost_Libraries_
aus.
Beachten Sie, dass boost::regex_replace()
den gesamten String nach einem regulären Ausdruck durchsucht. So werden im Beispiel 8.3 alle drei Leerzeichen durch einen Unterstrich ersetzt.
#include <boost/regex.hpp>
#include <string>
#include <iostream>
int main()
{
std::string s = "Boost Libraries";
boost::regex expr{"(\\w+)\\s(\\w+)"};
std::string fmt{"\\2 \\1"};
std::cout << boost::regex_replace(s, expr, fmt) << '\n';
}
Im Formatierungsstring kann auf Substrings zugegriffen werden, die durch Gruppierungen im regulären Ausdruck zurückgegeben werden. So können wie im Beispiel 8.4 die Positionen der beiden Wörter getauscht werden, so dass als Ergebnis Libraries Boost
ausgegeben wird.
Beachten Sie, dass es verschiedene Standards für reguläre Ausdrücke und Formatierungsstrings gibt. Für alle drei vorgestellten Funktionen kann ein weiterer Parameter übergeben werden, mit dem ein bestimmter Standard ausgewählt werden kann. Außerdem kann zum Beispiel angegeben werden, dass Sonderzeichen in einem Formatierungsstring nicht interpretiert werden sollen, sondern der Formatierungsstring komplett den String ersetzen soll, auf den der reguläre Ausdruck zutrifft.
#include <boost/regex.hpp>
#include <string>
#include <iostream>
int main()
{
std::string s = "Boost Libraries";
boost::regex expr{"(\\w+)\\s(\\w+)"};
std::string fmt{"\\2 \\1"};
std::cout << boost::regex_replace(s, expr, fmt,
boost::regex_constants::format_literal) << '\n';
}
Im Beispiel 8.5 wird das Flag boost::regex_constants::format_literal
als vierter Parameter an boost::regex_replace()
übergeben, um die Interpretation der Sonderzeichen im Formatierungsstring zu unterdrücken. Das Beispiel gibt als Ergebnis \2 \1
aus, da der gesamte String, auf den der reguläre Ausdruck zutrifft, mit dem Formatierungsstring ersetzt wird.
boost::regex_token_iterator
über Strings iterieren#include <boost/regex.hpp>
#include <string>
#include <iostream>
int main()
{
std::string s = "Boost Libraries";
boost::regex expr{"\\w+"};
boost::regex_token_iterator<std::string::iterator> it{s.begin(), s.end(),
expr};
boost::regex_token_iterator<std::string::iterator> end;
while (it != end)
std::cout << *it++ << '\n';
}
Boost.Regex bietet mit boost::regex_token_iterator
eine Klasse an, um mit einem regulären Ausdruck über einen String zu iterieren. So wird im Beispiel 8.6 über die beiden Wörter im String s iteriert. Dazu wird it mit Iteratoren auf s und dem regulären Ausdruck „\w+“ initialisiert. Über den Standardkonstruktor wird ein Iterator erzeugt, der das Ende einer Iteration markiert.
Beispiel 8.6 gibt Boost
und Libraries
aus.
boost::regex_token_iterator
auf Gruppierungen zugreifen#include <boost/regex.hpp>
#include <string>
#include <iostream>
int main()
{
std::string s = "Boost Libraries";
boost::regex expr{"(\\w)\\w+"};
boost::regex_token_iterator<std::string::iterator> it{s.begin(), s.end(),
expr, 1};
boost::regex_token_iterator<std::string::iterator> end;
while (it != end)
std::cout << *it++ << '\n';
}
Sie können dem Konstruktor von boost::regex_token_iterator
als zusätzlichen Parameter eine Zahl übergeben. Ist wie im Beispiel 8.7 1 angegeben, gibt der Iterator die erste Gruppierung im regulären Ausdruck zurück. Da „(\w)\w+“ als regulärer Ausdruck verwendet wird, gibt Beispiel 8.7 die Initialen B
und L
aus.
boost::regex_token_iterator
erlaubt es, -1 anzugeben. Der reguläre Ausdruck wird dann als Trennzeichen interpretiert. Ein Iterator, der mit -1 initialisiert wurde, gibt das zurück, auf was der reguläre Ausdruck nicht zutrifft.
#include <boost/regex.hpp>
#include <locale>
#include <string>
#include <iostream>
int main()
{
std::string s = "Boost k\xfct\xfcphaneleri";
boost::basic_regex<char, boost::cpp_regex_traits<char>> expr;
expr.imbue(std::locale{"Turkish"});
expr = "\\w+\\s\\w+";
std::cout << std::boolalpha << boost::regex_match(s, expr) << '\n';
}
Im Beispiel 8.8 wird ein Locale über imbue()
mit expr verknüpft. Dies geschieht, um den regulären Ausdruck auf den String „Boost kütüphaneleri“ anwenden zu können. Es handelt sich dabei um die türkische Übersetzung von „Die Boost-Bibliotheken“. Sollen die Umlaute im String vom regulären Ausdruck als gültige Buchstaben erkannt werden, muss das Locale gesetzt werden – andernfalls gibt boost::regex_match()
false
zurück.
Um einen Locale vom Typ std::locale
verwenden zu können, muss expr auf einer Regex-Klasse basieren, die mit dem Typ boost::cpp_regex_traits
instanziiert ist. Deswegen verwendet Beispiel 8.8 nicht boost::regex
, sondern boost::basic_regex<char, boost::cpp_regex_traits<char>>
. Über den zweiten Template-Parameter von boost::basic_regex
ist es möglich, indirekt den Parameter für imbue()
zu definieren. Nur bei boost::cpp_regex_traits
kann ein Locale-Objekt vom Typ std::locale
an imbue()
übergeben werden.
Ersetzen Sie die Angabe „Turkish“ mit „tr_TR“, wenn Sie das Beispiel auf einem POSIX-Betriebssystem ausführen möchten. Stellen Sie außerdem sicher, dass das Locale für den türkischen Sprach- und Kulturkreis installiert ist.
Beachten Sie, dass boost::regex
mit einem plattformabhängigen zweiten Parameter definiert ist. Unter Windows ist dies boost::w32_regex_traits
. Damit ist es möglich, einen LCID an imbue()
zu übergeben. Es handelt sich hierbei um eine Zahl, die unter Windows einen bestimmten Sprach- und Kulturkreis definiert. Wenn Sie plattformabhängigen Code schreiben möchten, müssen Sie wie im Beispiel 8.8 boost::cpp_regex_traits
explizit verwenden. Alternativ können Sie das Makro BOOST_REGEX_USE_CPP_LOCALE
definieren.