TOC

This article is currently in the process of being translated into German (~99% done).

Regulärer Ausdruck (Regex):

Regex Modifiers

Im vorherigen Artikel haben wir darüber gesprochen, was reguläre Ausdrücke sind und wie man sie in C# zum Suchen und Ersetzen nutzen kann. Zu diesem Zeitpunkt sollten Sie schon bemerkt haben, wie mächtig reguläre Ausdrücke sind und wie sie in vielen Situationen helfen können. Aber sie werden sogar noch hilfreicher, wenn man die möglichen modifier kennt.

Beim Arbeiten mit regulären Ausdrücken kann man einen oder mehrere modifier verwenden, um das Verhalten der Suche zu steuern. Zum Beispiel, ein Regex Suchprozess ist meistens case-sensitive, das bedeutet ein "a" ist nicht gleich "A". Allerdings möchte man in vielen Situationen dass das Suchergebnis case-insensitive ist, sodass das Zeichen "a" nur ein Buchstabe ist, unabhängig davon ob es groß oder klein geschrieben ist. Ergänzen Sie einfach die RegexOptions.IgnoreCase Option wenn sie die Regex Instanz erstellen und Ihr Suchergebnis wird case-insensitive sein.

Sie können alle verfügbaren Modifier in der RegexOptions Auflistung finden. Viele davon sind in allen Programmiersprachen, die den Regular Expression Standard unterstützen, gleich, während andere spezifisch für das .Net Framework sind.

Wie Sie im ersten Beispiel sehen können, werden Regex Modifier gewöhnlich als zweiter Parameter spezifiziert, wenn Sie eine Regex Instanz erstellen. Sie können mehre Modifier spezifizieren, indem Sie diese durch ein pipe (|) Zeichen wie folgt trennen:

new Regex("[a-z]+", RegexOptions.IgnoreCase | RegexOptions.Singleline);

Nun lassen Sie uns durch alle Modifier gehen um Ihnen eine Vorstellung darüber zu geben, wie diese funktionieren und was diese für uns tun können.

RegexOptions.IgnoreCase

DIes wird wahrscheinlich einer ihrer meist genutzten Modifier sein. Wie oben beschrieben, wir es deine Regular Expression von case-sensitive zu case-insensitive ändern. Das macht einen großen Unterschied, wie du in diesem Beispiel sehen kannst:

public void IgnoreCaseModifier()
{
	string testString = "Hello World";
	string regexString = @"^[a-z\s]+$";
	Regex caseSensitiveRegex = new Regex(regexString);
	Regex caseInsensitiveRegex = new Regex(regexString, RegexOptions.IgnoreCase);

	Console.WriteLine("Case-sensitive match: " + caseSensitiveRegex.IsMatch(testString));
	Console.WriteLine("Case-insensitive match: " + caseInsensitiveRegex.IsMatch(testString));
}

Wir geben einen einfachen Regex an, der nur Buchstaben (a-z) und Leerzeichen entsprechen soll. Anschließend benutzen wir ihn um Regex Instanzen zu erstellen: einen ohne den RegexOptions.IgnoreCase modifier und einen mit ihm welcher aus Klein- und Großbuchstaben und Leerzeichen besteht. Der output wird, wahrscheinlich nicht überraschend, wie folgt aussehen:

Case-sensitive match: False
Case-insensitive match: True

RegexOptions.Singleline

Der Punkt (.) steht in regulären Audrücken als Platzhalter für ein beliebiges Zeichen. Allerdings werden durch den Punkt keine Zeilenumbrüche miterfasst. Das bedeutet, dass der Punkt verwendet werden kann, um einer kompletten Zeile bestehend aus Buchstaben, Ziffern, Sonderzeichen etc. zu entsprechen. Aber die Entsprechung endet, sobald ein Zeilenumbruch gefunden wird. Wird hingegen der Singleline - modifier eingesetzt, werden auch Zeilenumbrüche durch den Punkt erfasst. Lassen Sie mich den Unterschied demonstrieren:

public void SinglelineModifier()
{
	string testString = 
						@"Hello World
						This string contains
						several lines";
	string regexString = ".*";
	
	Regex normalRegex = new Regex(regexString);
	Regex singlelineRegex = new Regex(regexString, RegexOptions.Singleline);			

	Console.WriteLine("Normal regex: " + normalRegex.Match(testString).Value);
	Console.WriteLine("Singleline regex: " + singlelineRegex.Match(testString).Value);
}

Die Ausgabe wird so aussehen:

Normal regex: Hello World

Singleline regex: Hello World
							This string contains
                            several lines

RegexOptions.Multiline

Wie wir in diesem Kapitel bereits gesagt haben bestehen reguläre Ausdrücke (Regular Expressions) aus vielen unterschiedlichen Zeichen, die bestimmte Aufgaben übernehmen. Ein weiteres Beispiel dafür sind diese beiden Zeichen: ^ und $. Wir haben diese bereits oben im Groß/Kleinschreibungs-Unterscheidungs-Beispiel verwendet, um den Anfang und das Ende einer Zeichenkette festzulegen [???]. Durch die Angabe des Multiline modifikators kann dieses Verhalten jedoch dahingehend geändert werden, dass nicht mehr der Anfang bzw. das Ende der gesamten Zeichenkette, sondern der Anfang bzw. das Ende von einzelnen Zeilen entsprechen. Das ist sehr nützlich, wenn man die Zeilen einzeln bearbeiten möchte. Hier folgt ein Beispiel:

public void MultilineModifier()
{
	string testString =
						@"Hello World
						This string contains
						several lines";
	string regexString = "^.*$";

	Regex singlelineRegex = new Regex(regexString, RegexOptions.Singleline);
	Regex multilineRegex = new Regex(regexString, RegexOptions.Multiline);

	Console.WriteLine("Singleline regex: " + singlelineRegex.Match(testString).Value);

	Console.WriteLine("Multiline regex:");
	MatchCollection matches = multilineRegex.Matches(testString);
	for(int i = 0; i < matches.Count; i++)
		Console.WriteLine("Line " + i + ": " + matches[i].Value.Trim());
}

Beachten Sie, wie ich eine Testzeichenkette verwende, die aus mehreren Zeilen besteht, und dann die unterschiedlichen Mechanismen des regulären Ausdrucks benutze: mit singlelineRegex wird die gesamte Testzeichenkette als eine einzige Zeile behandelt, obwohl diese Zeilenumbrüche enthält - so wie oben besprochen. Hingegen wird bei Verwendung von multilineRegex die Zeichenkette als aus mehreren Zeilen bestehend betrachtet, jede Zeile im Ergebnis ist ein Treffer. Die Regex.Matches() -Methode kann verwendet werden um jede einzelne Zeile zu erhalten und mit dieser dann zu arbeiten - in diesem Fall wird diese einfach auf der Konsole ausgegeben.

RegexOptions.Compiled

Auch wenn reguläre Audrücke eigentlich ziemlich schnell sind, können sie die Dinge etwas verlangsamen wenn sie zu komplex sind und zu oft ausgeführt werden, z.b. in einer Schleife. In dieser Situationen sollten Sie den RegexOptions.Compiled modifier verwenden, welcher es dem Framework erlaubt, das Regex in einer Assembly zu komplieren. Dies kostet zwar beim Erstellen etwas mehr Zeit im Vergleich zur normalen Instanziierung eines Regex-Objektes, aber es wird alle nachfolgenden Regex-Operationen (Vergleiche usw.) beschleunigen:

Regex compiledRegex = new Regex("[a-z]*", RegexOptions.Compiled);

Mehr modifier

Die obigen modifier sind die interessantesten, aber hier sind ein paar mehr durch die wir etwas schneller durchgehen:

  • RegexOptions.CultureInvariant: Dieser modifier bewirkt, dass kulturelle Unterschiede der Sprache ignoriert werden. (Leider wurde im englischen Original kein Beispiel dafür angegeben, möglicherweise handelt es sich hierbei um solche Dinge wie diacritical insensitive, also beispielsweise die Gleichbehandlung von Umlauten mit den jeweiligen unveränderten Vokalen (a-ä, o-ö, u-ü) - Bitte verifizieren und gegebenenfalls korrigieren!). Diese Option ist vor allem dann relevant, wenn mit unterschiedlichen nicht-englischen Sprachen gearbeitet wird.
  • RegexOptions.ECMAScript: Dieser modifier ändert die .NET - spezifische Regex-Variante zum ECMAScript Standard. Dies sollte kaum einmal notwendig sein.
  • RegexOptions.ExplicitCapture: Normalerweise werden mit runden Klammern in einem regulären Ausdruck so genannte "capturing groups" festgelegt. Auf die capturing groups kann man mit Hilfe eines Index zugreifen. Wenn der ExplicitCapture modifier angegeben wird, ändert sich das Verhalten dahingehend, dass nur benannte Gruppen als "capturing groups" für den späteren Zugriff gespeichert werden.
  • RegexOptions.IgnorePatternWhitespace: Wenn dieser modifier aktiviert ist, werden whitespace-Zeichen (Leerzeichen, Tab, Zeilenumbrüche (?)) in der Regex ignoriert und man kann dann sogar Kommentare in die Regex einbauen, indem diesen ein Rautezeichen (#) vorangestellt wird.
  • RegexOptions.RightToLeft: Der Vergleich erfolgt linksläufig ("arabische Schreibrichtung") - anstelle der voreingestellten Rechtsläufigkeit.

Zusammenfassung

Wie Sie sehen können, gibt es viele wichtige Regex modifier die Sie kennen sollten um die Vorteile von regulären Ausdrücken voll zu nutzen und so viele Anwendungsmöglichkeiten wie möglich zu unterstützen.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!