namespace cpp

C++ lernen, kennen, anwenden

Benutzer-Werkzeuge

Webseiten-Werkzeuge


kennen:include:regex

<regex>

Überblick

Suchmuster (reguläre Ausdrücke) ermöglichen effizientes Prüfen, Erkennen, Suchen, Filtern und Ersetzen in Zeichenketten. Die Klasse std::regex bildet einen endlichen Automaten zum Verarbeiten regulärer Ausdrücke. Die Fehlerbehandlung erfolgt über die Ausnahme std::regex_error. Die Klassen der <regex>-Bibliothek besitzen Varianten für wstring-Zeichenketten (wregex, wsmatch).

Weitergehende Informationen:

Validieren

Die Übereinstimmung der gesamten Zeichenkette wird geprüft mit

std::string s = "user@example.com";
std::regex rex;
rex = "[a-z0-9_-]+(\\.[a-z0-9_-]+)*@[a-z0-9_-]+(\\.[a-z0-9_-]+)+";
 
if (std::regex_match(s, rex)) /*  ist eine e-Mail-Adresse */ ;

In regulären Ausdrücken auftretende fallende Schrägstriche (Backslash) sind als \\ zu entwerten. In solchen Fällen ist ein raw string R"delim(…)delim" vorzuziehen:

rex = R"__([a-z0-9_-]+(\.[a-z0-9_-]+)*@[a-z0-9_-]+(\.[a-z0-9_-]+)+)__";

Suchen

Das Vorkommen von Teilzeichenketten, die regulären Ausdrücken entsprechen, wird mit

if (std::regex_search(s, rex)) /* vorhanden */; 

geprüft. Übereinstimmende Bereiche einer Durchmusterung lassen sich in std::smatch ablegen und nachfolgend verarbeiten:

std::string s = "Premiere Hobbit 21.12.2012";
std::regex regex(R"_((\d{1,2})\.(\d{1,2})\.(\d{4}|\d{2}))_"); 
std::smatch matches;
if (std::regex_search(s, matches, regex))
{
  std::string date = matches[0];
  std::string day = matches[1], month = matches[2], year = matches[3];
  // ...
} 

Der gefundene Gesamtausdruck liegt in matches[0]. Durch runde Klammern markierte Teilausdrücke in weiteren Elementen matches[i] mit i < matches.size().

Ersetzen

Der Ausdruck

std::regex_replace(original, regex, ersatz)

liefert eine neue Zeichenkette, in der gegenüber dem Original alle Übereinstimmungen mit dem regulären Ausdruck durch die Ersatz-Zeichenkette ausgetauscht sind.

Mit dem optionalen Parameter std::regex_constants::format_first_only wird der Austausch auf das erste Vorkommen beschränkt.

Regex-Tester

Reguläre Ausdrücke können recht komplex werden. Zum Testen empfiehlt sich ein kleines Programm (nach http://onlamp.com/pub/a/onlamp/2006/04/06/boostregex.html):

regexdemo.cpp
// modified from: http://onlamp.com/pub/a/onlamp/2006/04/06/boostregex.html?page=3
 
#include <iostream>
#include <string>
#include <regex>
 
int main( ) 
{
  while (true)
  {
    std::string expr, s;
    std::cout << "Expression: ";
    std::getline(std::cin, expr);
    if (!std::cin || expr == "quit") return 0; 
    std::cout << "String:     ";
    std::getline(std::cin, s);
    try
    {
      std::smatch matches;
      if (std::regex_match(s, matches, std::regex(expr)))
      {
        // matches[0] contains the original string.
        // matches[n] contains a sub_match object for each matching subexpression
        for (size_t i = 0; i < matches.size(); i++)
        {
          // sub_match is pair of iterators to the first
          // and one past the last chars of the matching subexpression
          // (matches[i].first, matches[i].second); 
          std::string match = matches[i];
          std::cout << "\tmatches[" << i << "] = " << match << '\n';
        }
      }
      else std::cout << "The regexp \"" << expr 
                     << "\" does not match \"" << s << "\"\n";
    }
    catch (std::regex_error& e)
    {
      std::cout << expr << " is not a valid regular expression: \""
                << e.what() << "\"\n";
    }
  }
  return 0;
}

Klassen

 class regex;
 class wregex;

Beschreibung: Regulärer Ausdruck.

Konstruktor: regex(s, syntaxoptions = std::regex_constants::ECMAScript).

 class smatch;
 class wmatch;
 class cmatch;
 class wcmatch;

Beschreibung: Container für Übereinstimmungen (Paare von Iteratoren).

 class regex_error;

Beschreibung: Ausnahme bei Durchmusterung / Syntaxfehler im regulären Ausdruck.

Funktionen

bool regex_match(const string& s, const regex& e, match_flag_type flags = match_default)
bool regex_match(const string& s, smatch& m, const regex& e, match_flag_type flags = match_default)
bool regex_match(Bi first, Bi last, const regex& e, match_flag_type flags = match_default)
bool regex_match(Bi first, Bi last, smatch& m, const regex& e, match_flag_type flags = match_default)

Beschreibung: Findet Übereinstimmungen der Zeichenkette s mit dem regulären Ausdruck e. Iteratorpaare der übereinstimmenden Teilbereiche werden im Container m abgelegt.

string regex_replace(const string& s, const regex& e, const string& fmt, match_flag_type flags = match_default)
Out    regex_replace(Out out, Bi first, Bi last, const regex& e, const string& fmt, match_flag_type flags = match_default)

Beschreibung: Ersetzt Übereinstimmungen eines Zeichenbereiches [first,last) bzw. der Zeichenkette s mit dem regulären Ausdruck e durch den Inhalt der Zeichenkette fmt.

bool regex_search(const string& s, const regex& e, match_flag_type flags = match_default)
bool regex_search(const string& s, smatch& m, const regex& e, match_flag_type flags = match_default)
bool regex_search(Bi first, Bi last, const regex& e, match_flag_type flags = match_default)
bool regex_search(Bi first, Bi last, smatch& m, const regex& e, match_flag_type flags = match_default)

Beschreibung: Ersetzt Übereinstimmungen eines Zeichenbereiches [first,last) bzw. der Zeichenkette s mit dem regulären Ausdruck e durch den Inhalt der Zeichenkette fmt. Iteratorpaare der übereinstimmenden Teilbereiche werden im Container m abgelegt.

Konstanten

Regex-Syntax-Optionen in std::regex_constants:

icase keine Unterscheidung von Groß- und Kleinbuchstaben
nosubs keine Teilausdrücke abspeichern
optimize schnellere Durchmusterung (auf Kosten der Zeit zum Aufbau des regulären Ausdrucks)
collate Buchstabenbereiche wie '[a-z]' richten sich nach Lokale
ECMAScript Regex nach ECMA-262-1999 (Vorgabewert)
basic POSIX-Regex
extended erweiterte POSIX-Regex
awk Regex wie in awk
grep Regex wie in grep
egrep Regex wie in grep -E

Optionen der Durchmusterung in std::regex_constants:

match_default Vorgabewert
match_not_bol erstes Zeichen wird nicht als Zeilenanfang betrachtet
match_not_eol letztes Zeichen wird nicht als Zeilenende betrachtet
match_not_bow erstes Zeichen wird nicht als Wortanfang betrachtet
match_not_eow letztes Zeichen wird nicht als Wortende betrachtet
match_any mehrere Übereinstimmungen mit dem Ausdruck möglich
match_not_null leere Zeichenkette ist kein Treffer
match_continuous Übereinstimmung muss mit dem ersten Zeichen beginnen
match_prev_avail –first ist gültige Iteratorposition

Optionen zum Suchen/Ersetzen in std::regex_constants:

format_default alle nicht-überlappenden Übereinstimmungen finden nach ECMA-262
format_sed Ersetzungen wie unter sed
format_no_copy nicht übereinstimmende Teile nicht ins Ziel übertragen
format_first_only nur erste Übereinstimmung finden / ersetzen
kennen/include/regex.txt · Zuletzt geändert: 2019-03-31 16:52 von rrichter