Die Regex-Funktionen

Einfache Regex-Funktionen zur direkten Stringmanipulation

Die Funktionen RegexRemove und RegexReplace dienen dazu unkompliziert Teilzeichenketten anhand eines regulären Ausdrucks aus einem String zu löschen bzw. zu ersetzen.

string strSubject = "abc1234def789";
RegexRemove(strSubject, "\\d"); //strSubject == "abcdef"
string strSubject = "abcXYZdef123";
RegexReplace(strSubject, "\\d|[A-Z]", "."); //strSubject == "abc...def..."

Siehe auch RegexRemove, RegexReplace

Mit 'Victory Regex-Designer' reguläre Ausdrücke entwickeln und testen

Die Anwendung 'Victory Regex-Designer', die der Entwicklungsumgebung beiliegt, hilft beim Erstellen von regulären Ausdrücken. Jede Änderung in der Oberfläche zeigt sofort die Auswirkung auf die Übereinstimmungen, ob ein Fehler im regulären Ausdruck vorhanden ist und stellt auch einen möglichen Austausch (Replace) von Übereinstimmungen dar. Ein fertiger regulärer Ausdruck kann dann einfach in die Zwischenablage kopiert werden, um in dann in Victory einzufügen.

Grundlagen zum Arbeiten mit Regex-Funktionen

Die Regex-Funktionen ermöglichen eine Mustersuche auf Grundlage regulärer Ausdrücke. Reguläre Ausdrücke, hier Regex-Pattern (Muster), sind ein mächtiges Hilfsmittel zum Bearbeiten und Auswerten von Strings (Zeichenfolgen).

Grundfunktion

 

Überprüfen

Ein Regex-Pattern kann überprüfen ob eine Teilzeichenkette bestimmte Kriterien erfüllt, z.B. ob eine numerische Zeichenfolge enthalten ist oder ob ein String einen bestimmten Aufbau besitzt.

Suchen

Ein Regex-Pattern kann mehr als nur nach Teilzeichenketten suchen. So kann bei einer Suche angegeben werden, dass neben einer Übereinstimmung auch ein Ausschluss bestimmter anderer Muster gegeben sein muss.

Suchen und Ersetzen

Ein Regex-Pattern kann nach Teilzeichenketten suchen und diese gegen eine andere Zeichenkette austauschen. Wobei auch darauf geachtet werden kann, dass bestimmte Übereinstimmungen nicht ersetzt werden, z.B. wenn in einem String 'ID-1234 ID-3453 ID6232 ID-7623 ID8343' nur alle 'ID' gegen ein 'ID-' getauscht werden sollen und nicht auch 'ID-' gegen 'ID--'.

Extrahieren

Ein Regex-Pattern kann verwendet werden um aus einem String anhand eines bestimmten Aufbaus einzelne Teilzeichenketten herauszufiltern.
So können aus dem String  '123V 23A 345°C, 157V 43A 288°C' die einzelnen Pakete Spannung, Strom und Temperatur mit einem RegexGlobalMatch gefunden und auslesbar gemacht werden.

Die in Victory implementierten Regex-Funktion sind kompatiblen zu den regulären Ausdrücken von PERL.

Ein regulärer Ausdruck rxPattern wird aus einem Filtermuster strPattern und den Filteroptionen PatternOptions erzeugt.

Im einfachsten Fall kann das Filtermuster nur ein Text sein ohne Angabe einer Filteroptionen. Der Regex-Verweis rxPattern wird mit der Funktion RegexCreate erzeugt.

value rxPattern;
RegexCreate(rxPattern, "ein Muster"); 

Mit der Funktion RegexSetPattern kann dem Regex-Verweise rxPattern ein neues Filtermuster zugewiesen werden.

RegexSetPattern(rxPattern, "neues Muster");

Wie in Victory üblich, muss für ein Backslash '\' in konstanten Texten ein Doppelbackslash '\\' eingegeben werden. D.h. bei allen Beispielen, die zu regulären Ausdrücken im Internet oder sonstiger Literatur gefunden werden, muss ein Backslash im Filtermustertext gegen ein Doppelbackslash ausgetauscht werden. Stammt der Filterausdruck z.B. aus dem Bauelement Eingabe der Visualisierung, so gilt dies nicht.

// Filtermuster für zwei numerische Zeichen gefolgt von einem Leerzeichen und einem Wort
// als Eingabetext '\d\d \w+'
RegexCreate(rxPattern, "\\d\\d \\w+");
// Filtermuster für Backslash '\'
// als Eingabetext '\\'
RegexCreate(rxPattern, "\\\\");

Die Funktion RegexGetPattern liefert das aktuelle Filtermuster.

string strPattern;
RegexCreate(rxPattern, "ein drittes Muster");
RegexGetPattern(rxPattern, strPattern); //strPattern == "ein drittes Muster"

Die Art und Weise wie mit dem Filtermuster gearbeitet werden soll, kann über das Setzen der PatternOptions vorgeben werden. So kann dem Regex-Verweis rxPattern mit REGEX_Pattern_CaseInsensitiveOption vorgegeben werden, dass nicht auf die Groß-/Kleinschreibung geachtet werden soll.

// stimmt nun mit "Victory" und auch "victory", "VICTORY", "viCtorY", etc. überein.
RegexCreate(rxPattern, "Victory", REGEX_Pattern_CaseInsensitiveOption);

Die beiden Funktionen RegexMatch und RegexGlobalMatch durchsuchen den Text strSubject nach Übereinstimmungen, anhand der Regeln des Regex-Verweises rxPattern.

Einfache Übereinstimmung

Das Prüfen auf eine einfache Übereinstimmung mit der Zeichenfolge strSubject wird mit RegexMatch ausgeführt. Das Ergebnis ist ein RegexMatch-Verweis rxMatch, der das Ergebnis der Analyse enthält.

value rxPattern, rxMatch, hasMatch;
// sucht zwei numerische Zeichen gefolgt von einem Leerzeichen und einem Wort
RegexCreate(rxPattern, "\\d\\d \\w+");
RegexMatch(rxPattern, rxMatch, "abc123 def");
hasMatch = RegexMatchHasMatch(rxMatch); // hasMatch == true

Wenn eine Übereinstimmung vorliegt, kann mit der impliziten Erfassungsguppe 0 die Teilzeichenkette ausgelesen werden, die mit dem Filtermuster komplett übereinstimmt.

value rxPattern, rxMatch, hasMatch;
string matched;
RegexCreate(rxPattern, "\\d\\d \\w+");
RegexMatch(rxPattern, rxMatch, "abc123 def");
if (RegexMatchHasMatch(rxMatch))
    matched = RegexMatchCaptured(rxMatch, 0); // matched == "23 def"
end

Es ist auch möglich die Suche an einer beliebigen Stelle im String strSubject zu beginnen, hierzu wird bei RegexMatch der Offset genutzt. Im nachfolgenden Beispiel liefert "12 abc" keine Übereinstimmung, da die Suche bei Offset 1 beginnt:

value rxPattern, rxMatch, hasMatch;
string matched;
RegexCreate(rxPattern, "\\d\\d \\w+");
RegexMatch(rxPattern, rxMatch, "12 abc 45 def", 1);
if (RegexMatchHasMatch(rxMatch))
    matched = RegexMatchCaptured(rxMatch, 0); // matched == "45 def"
end

Eine erfasste Übereinstimmung auslesen

Der RegexMatch-Verweis rxMatch enthält auch Informationen über Teilzeichenketten die als Übereinstimmungsgruppen im Filtermuster strPattern hinterlegt sind. Mit der Funktion RegexMatchCaptured können diese Gruppen ausgelesen werden:

value rxPattern, rxMatch, hasMatch;
string matched, day, month, year;
RegexCreate(rxPattern, "^(\\d\\d).(\\d\\d).(\\d\\d\\d\\d)$");
RegexMatch(rxPattern, rxMatch, "04.10.2005");
if (RegexMatchHasMatch(rxMatch))
    matched = RegexMatchCaptured(rxMatch, 0); // matched == "04.10.2005"
    day = RegexMatchCaptured(rxMatch, 1);     // day == "04"
    month = RegexMatchCaptured(rxMatch, 2);   // month == "10"
    year = RegexMatchCaptured(rxMatch, 3);    // year == "2005"
end

Die Erfassungsgruppe 0 (die implizite Erfassungsgruppe) beinhaltet immer die komplette Übereinstimmung. Erfasste Gruppen können ab Index 1 durchnummeriert abrufen werden.

Ebenso ist es möglich die Start- und Endposition einer Übereinstimmung im String strSubject auszulesen, hierzu dienen die Funktionen RegexMatchCapturedStart und RegexMatchCapturedEnd:

value rxPattern, rxMatch, hasMatch;
string matched;
value startPos, endPos;
RegexCreate(rxPattern, "abc(\\d+)def");
RegexMatch(rxPattern, rxMatch, "XYZabc123defXYZ");
if (RegexMatchHasMatch(rxMatch))
    matched = RegexMatchCaptured(rxMatch, 0);       // matched == "123"
    startPos = RegexMatchCapturedStart(rxMatch, 1); // startPos == 6
    endPos = RegexMatchCapturedEnd(rxMatch, 1);     // endPos == 9
end

Alle RegexMatchCaptured-Funktionen können anstelle des Gruppenindex auch mit dem Namen der 'benannten Gruppe' aufgerufen werden:

value rxPattern, rxMatch, hasMatch;
string matched, day, month, year;
RegexCreate(rxPattern, "^(<?day>\\d\\d).(<?month>\\d\\d).(<?year>\\d\\d\\d\\d)$");
RegexMatch(rxPattern, rxMatch, "04.10.2005");
if (RegexMatchHasMatch(rxMatch))
    matched = RegexMatchCaptured(rxMatch, 0);     // matched == "04.10.2005"
    day = RegexMatchCaptured(rxMatch, "day");     // day == "04"
    month = RegexMatchCaptured(rxMatch, "month"); // month == "10"
    year = RegexMatchCaptured(rxMatch, "year");   // year == "2005"
end

Mehrfache Übereinstimmungen

Mit RegexGlobalMatch können mehrfache Übereinstimmungen mit dem Filtermuster strPattern im String strSubject gefunden werden. Als Beispiel sollen alle Wörter in einem String gefunden werden, hierzu gilt das Filtermuster '\w+':

value rxPattern, rxIterator;
RegexCreate(rxPattern, "(\\w+)");
RegexGlobalMatch(rxPattern, rxIterator, "Victory - the visual factory");

Die Funktion RegexGlobalMatch liefert einen RegexIterator-Verweis rxIterator mit dem die RegexMatch-Verweis Ergebnisse abgeholt werden können.

Nach dem Aufruf von RegexGlobalMatch zeigt rxIterator auf ein Element vor dem ersten Ergebnis. Mit RegexIteratorHasNext kann geprüft werden, ob ein nächstes Ergebnis vorhanden ist, wenn ja dann kann dieses Ergebnis mit RegexIteratorNext abgerufen werden. Hierdurch verschiebt sich der Lesezeiger von rxIterator auf dieses Element. Ein erneutes Prüfen mit RegexIteratorHasNext gibt zurück, ob ein weiteres Ergebnis vorhanden ist. Wenn ja, kann dieses wieder mit RegexIteratorNext abgerufen werden, wodurch sich der Lesezeiger von rxIterator nun auf dieses Element verschiebt... usw. bis RegexIteratorHasNext false zurück liefert, da alle Übereinstimmungen ausgelesen wurden.

value rxPattern, rxIterator;
RegexCreate(rxPattern, "(\\w+)");
RegexGlobalMatch(rxPattern, rxIterator, "Victory - the visual factory");
while (RegexIteratorHasNext(rxIterator))
    rxMatch = RegexIteratorNext(rxIterator);
    matched += RegexMatchCaptured(rxMatch, 1);
    matched += ".";
end
// matched == "Victory.the.visual.factory."

Siehe auch RegexCreate, RegexGetPattern, RegexSetPattern, RegexClose, RegexGetLastError, RegexMatch, RegexGlobalMatch, RegexMatchHasMatch, RegexMatchHasPartialMatch, RegexMatchCaptured, RegexIteratorHasNext, RegexIteratorNext, RegexIteratorPeekNext, RegexMatchCapturedStart, RegexMatchCapturedLength, RegexMatchCapturedEnd, RegexRemove, RegexReplace