Optionen für reguläre Ausdrücke
Standardmäßig wird beim Vergleich einer Eingabezeichenfolge mit Literalzeichen in einem Muster eines regulären Ausdrucks die Groß-/Kleinschreibung beachtet, Leerstellen in einem Muster eines regulären Ausdrucks werden als literale Leerstellenzeichen interpretiert, und Erfassungsgruppen in einem regulären Ausdruck werden implizit sowie explizit benannt. Sie können diese und andere Aspekte des Standardverhaltens regulärer Ausdrücke ändern, indem Sie Optionen für reguläre Ausdrücke angeben. Einige dieser Optionen, die in der folgenden Tabelle aufgeführt sind, können inline als Teil des Musters eines regulären Ausdrucks enthalten sein, oder sie können für einen System.Text.RegularExpressions.Regex-Klassenkonstruktor oder eine statische Musterabgleichsmethode als System.Text.RegularExpressions.RegexOptions-Enumerationswert angegeben werden.
RegexOptions -Member |
Inlinezeichen | Effekt | Weitere Informationen |
---|---|---|---|
None | Nicht verfügbar | Standardverfahren verwenden. | Standardoptionen |
IgnoreCase | i |
Groß-/Kleinschreibung bei der Suche ignorieren | Übereinstimmung ohne Berücksichtigung der Groß-/Kleinschreibung |
Multiline | m |
Verwenden Sie den Mehrzeilenmodus, in dem ^ und $ den Anfang und das Ende jeder Zeile (und nicht den Anfang und das Ende der Eingabezeichenfolge) angeben. |
Mehrzeilenmodus |
Singleline | s |
Verwenden Sie Einzeilenmodus, in dem der Punkt (.) den einzelnen Zeichen entspricht (anstatt allen Zeichen mit Ausnahme von \n ). |
Einzeilenmodus |
ExplicitCapture | n |
Unbenannte Gruppen nicht erfassen Die einzigen gültigen Erfassungen sind explizit benannte oder nummerierte Gruppen mit dem Format (?< Name> Teilausdruck) . |
Nur explizite Erfassungen |
Compiled | Nicht verfügbar | Kompiliert den regulären Ausdruck in eine Assembly. | Kompilierte reguläre Ausdrücke |
IgnorePatternWhitespace | x |
Schließt Leerstellen ohne Escapezeichen vom Muster aus und aktiviert Kommentare nach einem Nummernzeichen (# ). |
Leerstellen ignorieren |
RightToLeft | Nicht verfügbar | Ändert die Suchrichtung. Die Suche wird von rechts nach links und nicht von links nach rechts durchgeführt. | Rechts-nach-links-Modus |
ECMAScript | Nicht verfügbar | ECMAScript-kompatibles Verhalten für den Ausdruck aktivieren. | ECMAScript-Vergleichsverhalten |
CultureInvariant | Nicht verfügbar | Ignoriert kulturelle Unterschiede in der Sprache. | Vergleiche mit der invarianten Kultur |
NonBacktracking | Nicht verfügbar | Führen Sie den Abgleich mithilfe eines Ansatzes durch, der Rückverfolgungen vermeidet und lineare Zeitverarbeitung in der Länge der Eingabe garantiert. (Verfügbar in .NET 7 und höheren Versionen.) | Nicht zurückverfolgender Modus |
Angeben von Optionen
Sie können Optionen für reguläre Ausdrücke mit einer von drei Methoden angeben:
Im
options
-Parameter eines System.Text.RegularExpressions.Regex-Klassenkonstruktors oder einer statischen (Shared
in Visual Basic) Mustervergleichsmethode, z. B. Regex(String, RegexOptions) oder Regex.Match(String, String, RegexOptions). Deroptions
-Parameter ist eine bitweise OR-Kombination von aufgezählten System.Text.RegularExpressions.RegexOptions-Werten.Wenn Optionen mit dem
options
-Parameter eines Klassenkonstruktors an eine Regex-Instanz übergeben werden, werden die Optionen der System.Text.RegularExpressions.RegexOptions-Eigenschaft zugewiesen. Die System.Text.RegularExpressions.RegexOptions-Eigenschaft gibt jedoch nicht die Inlineoptionen des eigentlichen Musters des regulären Ausdrucks wieder.Dies wird im folgenden Beispiel veranschaulicht. Es verwendet den
options
-Parameter der Regex.Match(String, String, RegexOptions)-Methode, um Vergleiche ohne Berücksichtigung der Groß-/Kleinschreibung zu ermöglichen und das Ignorieren von Leerzeichenmustern zu aktivieren, wenn Wörter identifiziert werden, die mit dem Buchstaben "d" beginnen.string pattern = @"d \w+ \s"; string input = "Dogs are decidedly good pets."; RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace; foreach (Match match in Regex.Matches(input, pattern, options)) Console.WriteLine("'{0}// found at index {1}.", match.Value, match.Index); // The example displays the following output: // 'Dogs // found at index 0. // 'decidedly // found at index 9.
Dim pattern As String = "d \w+ \s" Dim input As String = "Dogs are decidedly good pets." Dim options As RegexOptions = RegexOptions.IgnoreCase Or RegexOptions.IgnorePatternWhitespace For Each match As Match In Regex.Matches(input, pattern, options) Console.WriteLine("'{0}' found at index {1}.", match.Value, match.Index) Next ' The example displays the following output: ' 'Dogs ' found at index 0. ' 'decidedly ' found at index 9.
Durch das Übernehmen von Inlineoptionen in einem Muster eines regulären Ausdrucks mit der Syntax
(?imnsx-imnsx)
. Die Option gilt für das Muster ab dem Punkt, an dem die Option definiert wird, bis zum Ende des Musters oder zu dem Punkt, an dem die Definition der Option von einer anderen Inlineoption aufgehoben wird. Beachten Sie, dass die System.Text.RegularExpressions.RegexOptions-Eigenschaft einer Regex-Instanz diese Inlineoptionen nicht wiedergibt. Weitere Informationen finden Sie im Thema Verschiedene Konstrukte.Dies wird im folgenden Beispiel veranschaulicht. Dabei werden Inlineoptionen verwendet, um Vergleiche ohne Berücksichtigung der Groß-/Kleinschreibung zu ermöglichen und das Ignorieren von Leerzeichenmustern zu aktivieren, wenn Wörter identifiziert werden, die mit dem Buchstaben "d" beginnen.
string pattern = @"(?ix) d \w+ \s"; string input = "Dogs are decidedly good pets."; foreach (Match match in Regex.Matches(input, pattern)) Console.WriteLine("'{0}// found at index {1}.", match.Value, match.Index); // The example displays the following output: // 'Dogs // found at index 0. // 'decidedly // found at index 9.
Dim pattern As String = "\b(?ix) d \w+ \s" Dim input As String = "Dogs are decidedly good pets." For Each match As Match In Regex.Matches(input, pattern) Console.WriteLine("'{0}' found at index {1}.", match.Value, match.Index) Next ' The example displays the following output: ' 'Dogs ' found at index 0. ' 'decidedly ' found at index 9.
Durch das Übernehmen von Inlineoptionen in einem bestimmten Gruppierungskonstrukt in einem Muster eines regulären Ausdrucks mit der Syntax
(?imnsx-imnsx:
Teilausdruck)
. Kein Vorzeichen vor einer Gruppe von Optionen aktiviert diese Optionen. Ein Minuszeichen deaktiviert sie. (?
ist ein fester Bestandteil der Syntax des Sprachkonstrukts, der immer erforderlich ist, unabhängig davon, ob Optionen aktiviert oder deaktiviert sind.) Die Option wird nur auf diese Gruppe angewendet. Weitere Informationen finden Sie unter Gruppierungskonstrukte.Dies wird im folgenden Beispiel veranschaulicht. Dabei werden Inlineoptionen in einem Gruppierungskonstrukt verwendet, um Vergleiche ohne Berücksichtigung der Groß-/Kleinschreibung zu ermöglichen und das Ignorieren von Leerzeichenmustern zu aktivieren, wenn Wörter identifiziert werden, die mit dem Buchstaben "d" beginnen.
string pattern = @"\b(?ix: d \w+)\s"; string input = "Dogs are decidedly good pets."; foreach (Match match in Regex.Matches(input, pattern)) Console.WriteLine("'{0}// found at index {1}.", match.Value, match.Index); // The example displays the following output: // 'Dogs // found at index 0. // 'decidedly // found at index 9.
Dim pattern As String = "\b(?ix: d \w+)\s" Dim input As String = "Dogs are decidedly good pets." For Each match As Match In Regex.Matches(input, pattern) Console.WriteLine("'{0}' found at index {1}.", match.Value, match.Index) Next ' The example displays the following output: ' 'Dogs ' found at index 0. ' 'decidedly ' found at index 9.
Wenn Optionen inline angegeben sind, deaktiviert ein Minuszeichen (-
) vor einer Option oder einer Gruppe von Optionen diese Optionen. Das Inlinekonstrukt (?ix-ms)
aktiviert z. B. die RegexOptions.IgnoreCase-Option und die RegexOptions.IgnorePatternWhitespace-Option und deaktiviert die RegexOptions.Multiline-Option und die RegexOptions.Singleline-Option. Alle Optionen für reguläre Ausdrücke sind standardmäßig deaktiviert.
Hinweis
Wenn die Optionen für reguläre Ausdrücke im options
-Parameter eines Konstruktors oder Methodenaufrufs im Konflikt mit den Optionen stehen, die inline in einem Muster eines regulären Ausdrucks angegeben wurden, werden die Inlineoptionen verwendet.
Die folgenden fünf Optionen für reguläre Ausdrücke können sowohl mit dem options-Parameter als auch inline festgelegt werden:
Die folgenden fünf Optionen für reguläre Ausdrücke können mit dem options
-Parameter, jedoch nicht inline festgelegt werden:
Ermitteln von Optionen
Sie können ermitteln, welche Optionen für ein Regex-Objekt bereitgestellt wurden, als es instanziiert wurde, indem der Wert der schreibgeschützten Regex.Options-Eigenschaft abgerufen wird.
Um auf Vorhandensein einer anderen Option als RegexOptions.None zu testen, führen Sie eine AND-Operation mit dem Wert der Regex.Options-Eigenschaft und dem RegexOptions-Wert aus, für den Sie sich interessieren. Anschließend testen Sie, ob das Ergebnis diesem RegexOptions-Wert entspricht. Im folgenden Beispiel wird getestet, ob die RegexOptions.IgnoreCase-Option festgelegt wurde.
if ((rgx.Options & RegexOptions.IgnoreCase) == RegexOptions.IgnoreCase)
Console.WriteLine("Case-insensitive pattern comparison.");
else
Console.WriteLine("Case-sensitive pattern comparison.");
If (rgx.Options And RegexOptions.IgnoreCase) = RegexOptions.IgnoreCase Then
Console.WriteLine("Case-insensitive pattern comparison.")
Else
Console.WriteLine("Case-sensitive pattern comparison.")
End If
Zum Testen auf RegexOptions.None bestimmen Sie, ob der Wert der Regex.Options-Eigenschaft gleich RegexOptions.None ist, wie im folgenden Beispiel dargestellt.
if (rgx.Options == RegexOptions.None)
Console.WriteLine("No options have been set.");
If rgx.Options = RegexOptions.None Then
Console.WriteLine("No options have been set.")
End If
In den folgenden Abschnitten werden die Optionen aufgeführt, die von regulären .NET-Ausdrücken unterstützt werden.
Standardoptionen
Die RegexOptions.None-Option gibt an, dass keine Optionen angegeben wurden, und die Engine für reguläre Ausdrücke verwendet sein Standardverhalten. Hierzu gehören folgende Elemente:
Das Muster wird kanonisch und nicht als regulärer ECMAScript-Ausdruck interpretiert.
Das Muster eines regulären Ausdrucks wird von links nach rechts mit der Eingabezeichenfolge verglichen.
Bei Vergleichen wird die Groß-/Kleinschreibung berücksichtigt.
Die Sprachelemente
^
und$
geben den Anfang und das Ende der Eingabezeichenfolge an. Das Ende der Eingabezeichenfolge kann ein nachstehendes\n
-Zeilenvorschubzeichen sein.Das
.
-Sprachelement findet eine Entsprechung für jedes Zeichen außer\n
.Alle Leerstellen in einem Muster eines regulären Ausdrucks werden als literale Leerzeichen interpretiert.
Die Konventionen der aktuellen Kultur werden zum Vergleichen des Musters mit der Eingabezeichenfolge verwendet.
Erfassungsgruppen im Muster eines regulären Ausdrucks sind implizit und explizit.
Hinweis
Die RegexOptions.None-Option besitzt keine Inlineentsprechung. Wenn reguläre Ausdrucksoptionen inline übernommen werden, wird das Standardverhalten auf optionsweiser Basis durch Deaktivieren einer bestimmten Option wiederhergestellt. (?i)
aktiviert z. B. Vergleiche, bei denen nicht zwischen Groß- und Kleinschreibung unterschieden wird, und (?-i)
stellt das Standardverhalten mit Beachtung der Groß-/Kleinschreibung wieder her.
Da die RegexOptions.None-Option das Standardverhalten der Engine für reguläre Ausdrücke darstellt, wird sie selten explizit in einem Methodenaufruf angegeben. Stattdessen wird ein Konstruktor oder eine statische Mustervergleichsmethode ohne options
-Parameter aufgerufen.
Übereinstimmung ohne Berücksichtigung der Groß-/Kleinschreibung
Die IgnoreCase-Option oder die i
-Inlineoption stellt die Suche nach Übereinstimmungen ohne Berücksichtigung von Groß-/Kleinschreibung bereit. Standardmäßig werden die Groß-/Kleinschreibungskonventionen der aktuellen Kultur verwendet.
Im folgenden Beispiel wird das Muster eines regulären Ausdrucks \bthe\w*\b
definiert, das eine Entsprechung für alle Wörter findet, die mit "the" beginnen. Da der erste Aufruf der Match-Methode beim Vergleich standardmäßig die Groß-/Kleinschreibung beachtet, gibt die Ausgabe an, dass zur Zeichenfolge "The" am Anfang des Satzes keine Übereinstimmung gefunden wurde. Eine Entsprechung wird gefunden, wenn die Match-Methode mit der Einstellung IgnoreCase für die Optionen aufgerufen wird.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"\bthe\w*\b";
string input = "The man then told them about that event.";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index);
Console.WriteLine();
foreach (Match match in Regex.Matches(input, pattern,
RegexOptions.IgnoreCase))
Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index);
}
}
// The example displays the following output:
// Found then at index 8.
// Found them at index 18.
//
// Found The at index 0.
// Found then at index 8.
// Found them at index 18.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\bthe\w*\b"
Dim input As String = "The man then told them about that event."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index)
Next
Console.WriteLine()
For Each match As Match In Regex.Matches(input, pattern, _
RegexOptions.IgnoreCase)
Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index)
Next
End Sub
End Module
' The example displays the following output:
' Found then at index 8.
' Found them at index 18.
'
' Found The at index 0.
' Found then at index 8.
' Found them at index 18.
Im folgenden Beispiel wird das Muster eines regulären Ausdrucks aus dem vorherigen Beispiel so geändert, dass Inlineoptionen anstelle des options
-Parameters verwendet werden, um einen Vergleich ohne Berücksichtigung von Groß- und Kleinschreibung bereitzustellen. Das erste Muster definiert die Option zum Ignorieren der Groß-/Kleinschreibung in einem Gruppierungskonstrukt, das in der Zeichenfolge "the" nur für den Buchstaben "t" gilt. Da das Optionskonstrukt am Anfang des Musters auftritt, wendet das zweite Muster die Option zur Missachtung der Groß-/Kleinschreibung auf den gesamten regulären Ausdruck an.
using System;
using System.Text.RegularExpressions;
public class CaseExample
{
public static void Main()
{
string pattern = @"\b(?i:t)he\w*\b";
string input = "The man then told them about that event.";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index);
Console.WriteLine();
pattern = @"(?i)\bthe\w*\b";
foreach (Match match in Regex.Matches(input, pattern,
RegexOptions.IgnoreCase))
Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index);
}
}
// The example displays the following output:
// Found The at index 0.
// Found then at index 8.
// Found them at index 18.
//
// Found The at index 0.
// Found then at index 8.
// Found them at index 18.
Imports System.Text.RegularExpressions
Module CaseExample
Public Sub Main()
Dim pattern As String = "\b(?i:t)he\w*\b"
Dim input As String = "The man then told them about that event."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index)
Next
Console.WriteLine()
pattern = "(?i)\bthe\w*\b"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("Found {0} at index {1}.", match.Value, match.Index)
Next
End Sub
End Module
' The example displays the following output:
' Found The at index 0.
' Found then at index 8.
' Found them at index 18.
'
' Found The at index 0.
' Found then at index 8.
' Found them at index 18.
Mehrzeilenmodus
Die RegexOptions.Multiline-Option oder die m
Inlineoption aktiviert die Engine für reguläre Ausdrücke für die Behandlung einer Eingabezeichenfolge, die aus mehreren Zeilen besteht. Ändert die Bedeutung der Sprachelemente ^
und $
, sodass sie jeweils dem Anfang und dem Ende einer Zeile und nicht nur dem Anfang und dem Ende der Eingabezeichenfolge entsprechen.
In der Standardeinstellung ist $
nur am Ende der Eingabezeichenfolge erfolgreich. Wenn Sie die RegexOptions.Multiline-Option angeben, wird diese entweder dem Zeilenumbruchzeichen (\n
) oder dem Ende der Eingabezeichenfolge erfolgreich.
In keinem der beiden Fälle erkennt $
die Wagenrücklauf-/Zeilenvorschubzeichenkombination (\r\n
). $
ignoriert immer alle Wagenrückläufe (\r
). Um die Übereinstimmung mit \r\n
oder \n
zu beenden, verwenden Sie den Teilausdruck \r?$
anstelle von nur $
. Beachten Sie, dass dies den Teil \r
der Übereinstimmung ausmacht.
Im folgenden Beispiel werden die Namen und Ergebnisse von Bowlern extrahiert und in absteigender Reihenfolge sortiert einer SortedList<TKey,TValue>-Auflistung hinzugefügt. Die Matches-Methode wird zweimal aufgerufen. Im ersten Methodenaufruf ist der reguläre Ausdruck ^(\w+)\s(\d+)$
. Es werden keine Optionen festgelegt. Wie die Ausgabe zeigt, werden keine Übereinstimmungen gefunden, da die Engine für reguläre Ausdrücke das Eingabemuster nicht mit dem Anfang und dem Ende der Eingabezeichenfolge vergleichen kann. Im zweiten Methodenaufruf wurde der reguläre Ausdruck in ^(\w+)\s(\d+)\r?$
geändert und die Optionen wurden auf RegexOptions.Multiline festgelegt. Wie die Ausgabe zeigt, werden die Namen und Ergebnisse erfolgreich abgeglichen, und die Ergebnisse werden in absteigender Reihenfolge angezeigt.
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
public class Multiline1Example
{
public static void Main()
{
SortedList<int, string> scores = new SortedList<int, string>(new DescendingComparer1<int>());
string input = "Joe 164\n" +
"Sam 208\n" +
"Allison 211\n" +
"Gwen 171\n";
string pattern = @"^(\w+)\s(\d+)$";
bool matched = false;
Console.WriteLine("Without Multiline option:");
foreach (Match match in Regex.Matches(input, pattern))
{
scores.Add(Int32.Parse(match.Groups[2].Value), (string)match.Groups[1].Value);
matched = true;
}
if (!matched)
Console.WriteLine(" No matches.");
Console.WriteLine();
// Redefine pattern to handle multiple lines.
pattern = @"^(\w+)\s(\d+)\r*$";
Console.WriteLine("With multiline option:");
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.Multiline))
scores.Add(Int32.Parse(match.Groups[2].Value), (string)match.Groups[1].Value);
// List scores in descending order.
foreach (KeyValuePair<int, string> score in scores)
Console.WriteLine("{0}: {1}", score.Value, score.Key);
}
}
public class DescendingComparer1<T> : IComparer<T>
{
public int Compare(T x, T y)
{
return Comparer<T>.Default.Compare(x, y) * -1;
}
}
// The example displays the following output:
// Without Multiline option:
// No matches.
//
// With multiline option:
// Allison: 211
// Sam: 208
// Gwen: 171
// Joe: 164
Imports System.Collections.Generic
Imports System.Text.RegularExpressions
Module Multiline1Example
Public Sub Main()
Dim scores As New SortedList(Of Integer, String)(New DescendingComparer1(Of Integer)())
Dim input As String = "Joe 164" + vbCrLf +
"Sam 208" + vbCrLf +
"Allison 211" + vbCrLf +
"Gwen 171" + vbCrLf
Dim pattern As String = "^(\w+)\s(\d+)$"
Dim matched As Boolean = False
Console.WriteLine("Without Multiline option:")
For Each match As Match In Regex.Matches(input, pattern)
scores.Add(CInt(match.Groups(2).Value), match.Groups(1).Value)
matched = True
Next
If Not matched Then Console.WriteLine(" No matches.")
Console.WriteLine()
' Redefine pattern to handle multiple lines.
pattern = "^(\w+)\s(\d+)\r*$"
Console.WriteLine("With multiline option:")
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.Multiline)
scores.Add(CInt(match.Groups(2).Value), match.Groups(1).Value)
Next
' List scores in descending order.
For Each score As KeyValuePair(Of Integer, String) In scores
Console.WriteLine("{0}: {1}", score.Value, score.Key)
Next
End Sub
End Module
Public Class DescendingComparer1(Of T) : Implements IComparer(Of T)
Public Function Compare(x As T, y As T) As Integer _
Implements IComparer(Of T).Compare
Return Comparer(Of T).Default.Compare(x, y) * -1
End Function
End Class
' The example displays the following output:
' Without Multiline option:
' No matches.
'
' With multiline option:
' Allison: 211
' Sam: 208
' Gwen: 171
' Joe: 164
Das Muster für reguläre Ausdrücke ^(\w+)\s(\d+)\r*$
wird entsprechend der folgenden Tabelle definiert:
Muster | Beschreibung |
---|---|
^ |
Am Anfang der Zeile beginnen. |
(\w+) |
Übereinstimmung mit mindestens einem Wortzeichen. Dies ist die erste Erfassungsgruppe. |
\s |
Entsprechung für ein Leerraumzeichen finden. |
(\d+) |
Entsprechung für mindestens eine Dezimalstelle finden. Dies ist die zweite Erfassungsgruppe. |
\r? |
Entspricht null oder mehr Wagenrücklaufzeichen. |
$ |
Ende am Ende der Zeile. |
Das folgende Beispiel entspricht dem vorherigen, abgesehen davon, dass zum Festlegen der Mehrzeilenoption die Inlineoption (?m)
verwendet wird.
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
public class Multiline2Example
{
public static void Main()
{
SortedList<int, string> scores = new SortedList<int, string>(new DescendingComparer<int>());
string input = "Joe 164\n" +
"Sam 208\n" +
"Allison 211\n" +
"Gwen 171\n";
string pattern = @"(?m)^(\w+)\s(\d+)\r*$";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.Multiline))
scores.Add(Convert.ToInt32(match.Groups[2].Value), match.Groups[1].Value);
// List scores in descending order.
foreach (KeyValuePair<int, string> score in scores)
Console.WriteLine("{0}: {1}", score.Value, score.Key);
}
}
public class DescendingComparer<T> : IComparer<T>
{
public int Compare(T x, T y)
{
return Comparer<T>.Default.Compare(x, y) * -1;
}
}
// The example displays the following output:
// Allison: 211
// Sam: 208
// Gwen: 171
// Joe: 164
Imports System.Collections.Generic
Imports System.Text.RegularExpressions
Module Multiline2Example
Public Sub Main()
Dim scores As New SortedList(Of Integer, String)(New DescendingComparer(Of Integer)())
Dim input As String = "Joe 164" + vbCrLf +
"Sam 208" + vbCrLf +
"Allison 211" + vbCrLf +
"Gwen 171" + vbCrLf
Dim pattern As String = "(?m)^(\w+)\s(\d+)\r*$"
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.Multiline)
scores.Add(CInt(match.Groups(2).Value), match.Groups(1).Value)
Next
' List scores in descending order.
For Each score As KeyValuePair(Of Integer, String) In scores
Console.WriteLine("{0}: {1}", score.Value, score.Key)
Next
End Sub
End Module
Public Class DescendingComparer(Of T) : Implements IComparer(Of T)
Public Function Compare(x As T, y As T) As Integer _
Implements IComparer(Of T).Compare
Return Comparer(Of T).Default.Compare(x, y) * -1
End Function
End Class
' The example displays the following output:
' Allison: 211
' Sam: 208
' Gwen: 171
' Joe: 164
Einzeilenmodus
Die RegexOptions.Singleline-Option oder die s
Inlineoption sorgt dafür, dass die Engine für reguläre Ausdrücke die Eingabezeichenfolge so behandelt, als ob sie aus einer einzigen Zeile besteht. Es wird das Verhalten des Sprachelements Punkt (.
) geändert, sodass dieser jedem Zeichen entspricht, anstatt jedem Zeichen außer dem Zeilenumbruchzeichen \n
.
Im folgenden Beispiel wird veranschaulicht, wie sich das Verhalten des .
-Sprachelements ändert, wenn Sie die RegexOptions.Singleline-Option verwenden. Der reguläre ^.+
-Ausdruck beginnt am Anfang der Zeichenfolge und stimmt mit jedem Zeichen überein. Standardmäßig endet die Übereinstimmung am Ende der ersten Zeile. Das Muster für den regulären Ausdruck stimmt mit dem Wagenrücklaufzeichen (\r
), jedoch nicht mit \n
überein. Da die gesamte Eingabezeichenfolge von der RegexOptions.Singleline-Option als einzelne Zeile interpretiert wird, liegt für jedes enthaltene Zeichen eine Übereinstimmung vor, einschließlich \n
.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = "^.+";
string input = "This is one line and" + Environment.NewLine + "this is the second.";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine(Regex.Escape(match.Value));
Console.WriteLine();
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.Singleline))
Console.WriteLine(Regex.Escape(match.Value));
}
}
// The example displays the following output:
// This\ is\ one\ line\ and\r
//
// This\ is\ one\ line\ and\r\nthis\ is\ the\ second\.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "^.+"
Dim input As String = "This is one line and" + vbCrLf + "this is the second."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(Regex.Escape(match.Value))
Next
Console.WriteLine()
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.SingleLine)
Console.WriteLine(Regex.Escape(match.Value))
Next
End Sub
End Module
' The example displays the following output:
' This\ is\ one\ line\ and\r
'
' This\ is\ one\ line\ and\r\nthis\ is\ the\ second\.
Das folgende Beispiel entspricht dem vorherigen, abgesehen davon, dass zum Aktivieren der Einzelzeilenoption die Inlineoption (?s)
verwendet wird.
using System;
using System.Text.RegularExpressions;
public class SingleLineExample
{
public static void Main()
{
string pattern = "(?s)^.+";
string input = "This is one line and" + Environment.NewLine + "this is the second.";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine(Regex.Escape(match.Value));
}
}
// The example displays the following output:
// This\ is\ one\ line\ and\r\nthis\ is\ the\ second\.
Imports System.Text.RegularExpressions
Module SingleLineExample
Public Sub Main()
Dim pattern As String = "(?s)^.+"
Dim input As String = "This is one line and" + vbCrLf + "this is the second."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(Regex.Escape(match.Value))
Next
End Sub
End Module
' The example displays the following output:
' This\ is\ one\ line\ and\r\nthis\ is\ the\ second\.
Nur explizite Erfassungen
Standardmäßig werden Erfassungsgruppen durch die Verwendung von Klammern im Muster eines regulären Ausdrucks definiert. Benannten Gruppen wird über die (?<
Name>
Teilausdruck)
-Sprachoption ein Name oder eine Zahl zugewiesen, wohingegen auf unbenannte Gruppen über den Index zugegriffen werden kann. Im GroupCollection-Objekt gehen unbenannte Gruppen benannten Gruppen voraus.
Gruppierungskonstrukte werden häufig nur verwendet, um Quantifizierer für mehrere Sprachelemente zu übernehmen, und die erfassten Teilzeichenfolgen sind nicht von Bedeutung. Wenn beispielsweise der reguläre Ausdruck wie folgt lautet:
\b\(?((\w+),?\s?)+[\.!?]\)?
sollen nur Sätze mit einem Punkt, Ausrufezeichen oder Fragezeichen am Ende aus einem Dokument extrahiert werden. Nur der resultierende Satz (der durch das Match-Objekt dargestellt wird) ist von Interesse. Die einzelnen Wörter in der Auflistung sind irrelevant.
Erfassungsgruppen, die anschließend nicht verwendet werden, können speicherintensiv sein, da die Engine für reguläre Ausdrücke sowohl das GroupCollection- als auch das CaptureCollection-Auflistungsobjekt auffüllen muss. Alternativ können Sie entweder die RegexOptions.ExplicitCapture-Option oder die n
-Inlineoption verwenden, um anzugeben, dass die einzigen gültigen Erfassungen explizit benannte oder nummerierte Gruppen sind, die durch das Konstrukt (?<
Name>
Teilausdruck)
angegeben werden.
Das folgende Beispiel zeigt Informationen zu den Übereinstimmungen an, die vom Muster eines regulären Ausdrucks \b\(?((\w+),?\s?)+[\.!?]\)?
zurückgegeben werden, wenn die Match-Methode mit und ohne die RegexOptions.ExplicitCapture-Option aufgerufen wird. Wie die Ausgabe des ersten Methodenaufrufs zeigt, füllt die Engine für reguläre Ausdrücke das GroupCollection-Auflistungsobjekt und das CaptureCollection-Auflistungsobjekt vollständig mit Informationen zu erfassten Teilzeichenfolgen auf. Da die zweite Methode mit options
mit dem Wert RegexOptions.ExplicitCapture aufgerufen wird, werden keine Informationen zu Gruppen erfasst.
using System;
using System.Text.RegularExpressions;
public class Explicit1Example
{
public static void Main()
{
string input = "This is the first sentence. Is it the beginning " +
"of a literary masterpiece? I think not. Instead, " +
"it is a nonsensical paragraph.";
string pattern = @"\b\(?((?>\w+),?\s?)+[\.!?]\)?";
Console.WriteLine("With implicit captures:");
foreach (Match match in Regex.Matches(input, pattern))
{
Console.WriteLine("The match: {0}", match.Value);
int groupCtr = 0;
foreach (Group group in match.Groups)
{
Console.WriteLine(" Group {0}: {1}", groupCtr, group.Value);
groupCtr++;
int captureCtr = 0;
foreach (Capture capture in group.Captures)
{
Console.WriteLine(" Capture {0}: {1}", captureCtr, capture.Value);
captureCtr++;
}
}
}
Console.WriteLine();
Console.WriteLine("With explicit captures only:");
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.ExplicitCapture))
{
Console.WriteLine("The match: {0}", match.Value);
int groupCtr = 0;
foreach (Group group in match.Groups)
{
Console.WriteLine(" Group {0}: {1}", groupCtr, group.Value);
groupCtr++;
int captureCtr = 0;
foreach (Capture capture in group.Captures)
{
Console.WriteLine(" Capture {0}: {1}", captureCtr, capture.Value);
captureCtr++;
}
}
}
}
}
// The example displays the following output:
// With implicit captures:
// The match: This is the first sentence.
// Group 0: This is the first sentence.
// Capture 0: This is the first sentence.
// Group 1: sentence
// Capture 0: This
// Capture 1: is
// Capture 2: the
// Capture 3: first
// Capture 4: sentence
// Group 2: sentence
// Capture 0: This
// Capture 1: is
// Capture 2: the
// Capture 3: first
// Capture 4: sentence
// The match: Is it the beginning of a literary masterpiece?
// Group 0: Is it the beginning of a literary masterpiece?
// Capture 0: Is it the beginning of a literary masterpiece?
// Group 1: masterpiece
// Capture 0: Is
// Capture 1: it
// Capture 2: the
// Capture 3: beginning
// Capture 4: of
// Capture 5: a
// Capture 6: literary
// Capture 7: masterpiece
// Group 2: masterpiece
// Capture 0: Is
// Capture 1: it
// Capture 2: the
// Capture 3: beginning
// Capture 4: of
// Capture 5: a
// Capture 6: literary
// Capture 7: masterpiece
// The match: I think not.
// Group 0: I think not.
// Capture 0: I think not.
// Group 1: not
// Capture 0: I
// Capture 1: think
// Capture 2: not
// Group 2: not
// Capture 0: I
// Capture 1: think
// Capture 2: not
// The match: Instead, it is a nonsensical paragraph.
// Group 0: Instead, it is a nonsensical paragraph.
// Capture 0: Instead, it is a nonsensical paragraph.
// Group 1: paragraph
// Capture 0: Instead,
// Capture 1: it
// Capture 2: is
// Capture 3: a
// Capture 4: nonsensical
// Capture 5: paragraph
// Group 2: paragraph
// Capture 0: Instead
// Capture 1: it
// Capture 2: is
// Capture 3: a
// Capture 4: nonsensical
// Capture 5: paragraph
//
// With explicit captures only:
// The match: This is the first sentence.
// Group 0: This is the first sentence.
// Capture 0: This is the first sentence.
// The match: Is it the beginning of a literary masterpiece?
// Group 0: Is it the beginning of a literary masterpiece?
// Capture 0: Is it the beginning of a literary masterpiece?
// The match: I think not.
// Group 0: I think not.
// Capture 0: I think not.
// The match: Instead, it is a nonsensical paragraph.
// Group 0: Instead, it is a nonsensical paragraph.
// Capture 0: Instead, it is a nonsensical paragraph.
Imports System.Text.RegularExpressions
Module Explicit1Example
Public Sub Main()
Dim input As String = "This is the first sentence. Is it the beginning " +
"of a literary masterpiece? I think not. Instead, " +
"it is a nonsensical paragraph."
Dim pattern As String = "\b\(?((?>\w+),?\s?)+[\.!?]\)?"
Console.WriteLine("With implicit captures:")
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("The match: {0}", match.Value)
Dim groupCtr As Integer = 0
For Each group As Group In match.Groups
Console.WriteLine(" Group {0}: {1}", groupCtr, group.Value)
groupCtr += 1
Dim captureCtr As Integer = 0
For Each capture As Capture In group.Captures
Console.WriteLine(" Capture {0}: {1}", captureCtr, capture.Value)
captureCtr += 1
Next
Next
Next
Console.WriteLine()
Console.WriteLine("With explicit captures only:")
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.ExplicitCapture)
Console.WriteLine("The match: {0}", match.Value)
Dim groupCtr As Integer = 0
For Each group As Group In match.Groups
Console.WriteLine(" Group {0}: {1}", groupCtr, group.Value)
groupCtr += 1
Dim captureCtr As Integer = 0
For Each capture As Capture In group.Captures
Console.WriteLine(" Capture {0}: {1}", captureCtr, capture.Value)
captureCtr += 1
Next
Next
Next
End Sub
End Module
' The example displays the following output:
' With implicit captures:
' The match: This is the first sentence.
' Group 0: This is the first sentence.
' Capture 0: This is the first sentence.
' Group 1: sentence
' Capture 0: This
' Capture 1: is
' Capture 2: the
' Capture 3: first
' Capture 4: sentence
' Group 2: sentence
' Capture 0: This
' Capture 1: is
' Capture 2: the
' Capture 3: first
' Capture 4: sentence
' The match: Is it the beginning of a literary masterpiece?
' Group 0: Is it the beginning of a literary masterpiece?
' Capture 0: Is it the beginning of a literary masterpiece?
' Group 1: masterpiece
' Capture 0: Is
' Capture 1: it
' Capture 2: the
' Capture 3: beginning
' Capture 4: of
' Capture 5: a
' Capture 6: literary
' Capture 7: masterpiece
' Group 2: masterpiece
' Capture 0: Is
' Capture 1: it
' Capture 2: the
' Capture 3: beginning
' Capture 4: of
' Capture 5: a
' Capture 6: literary
' Capture 7: masterpiece
' The match: I think not.
' Group 0: I think not.
' Capture 0: I think not.
' Group 1: not
' Capture 0: I
' Capture 1: think
' Capture 2: not
' Group 2: not
' Capture 0: I
' Capture 1: think
' Capture 2: not
' The match: Instead, it is a nonsensical paragraph.
' Group 0: Instead, it is a nonsensical paragraph.
' Capture 0: Instead, it is a nonsensical paragraph.
' Group 1: paragraph
' Capture 0: Instead,
' Capture 1: it
' Capture 2: is
' Capture 3: a
' Capture 4: nonsensical
' Capture 5: paragraph
' Group 2: paragraph
' Capture 0: Instead
' Capture 1: it
' Capture 2: is
' Capture 3: a
' Capture 4: nonsensical
' Capture 5: paragraph
'
' With explicit captures only:
' The match: This is the first sentence.
' Group 0: This is the first sentence.
' Capture 0: This is the first sentence.
' The match: Is it the beginning of a literary masterpiece?
' Group 0: Is it the beginning of a literary masterpiece?
' Capture 0: Is it the beginning of a literary masterpiece?
' The match: I think not.
' Group 0: I think not.
' Capture 0: I think not.
' The match: Instead, it is a nonsensical paragraph.
' Group 0: Instead, it is a nonsensical paragraph.
' Capture 0: Instead, it is a nonsensical paragraph.
Das Muster für reguläre Ausdrücke \b\(?((?>\w+),?\s?)+[\.!?]\)?
ist entsprechend der folgenden Tabelle definiert.
Muster | Beschreibung |
---|---|
\b |
Bei einer Wortgrenze beginnen. |
\(? |
Sucht nach einer Übereinstimmung mit null oder einem Vorkommen der öffnenden Klammer ("("). |
(?>\w+),? |
Sucht nach einer Übereinstimmung mit einem oder mehreren Wortzeichen gefolgt von keinem oder einem Komma. Bei übereinstimmenden Wortzeichen findet keine Rückverfolgung statt. |
\s? |
Sucht nach einer Übereinstimmung mit keinem oder einem Leerzeichen. |
((\w+),?\s?)+ |
Entspricht der Kombination von mindestens einem Wortzeichen gefolgt von keinem oder einem Komma und keinem oder einem Leerzeichen (ein- oder mehrfach). |
[\.!?]\)? |
Entspricht jedem der drei Interpunktionszeichen, gefolgt von keiner oder einer schließenden Klammer (")"). |
Sie können auch das (?n)
-Inlineelement verwenden, um automatische Aufzeichnungen zu unterdrücken. Im folgenden Beispiel wird das vorherige Muster eines regulären Ausdrucks so geändert, dass das Inlineelement (?n)
anstelle der RegexOptions.ExplicitCapture-Option verwendet wird.
using System;
using System.Text.RegularExpressions;
public class Explicit2Example
{
public static void Main()
{
string input = "This is the first sentence. Is it the beginning " +
"of a literary masterpiece? I think not. Instead, " +
"it is a nonsensical paragraph.";
string pattern = @"(?n)\b\(?((?>\w+),?\s?)+[\.!?]\)?";
foreach (Match match in Regex.Matches(input, pattern))
{
Console.WriteLine("The match: {0}", match.Value);
int groupCtr = 0;
foreach (Group group in match.Groups)
{
Console.WriteLine(" Group {0}: {1}", groupCtr, group.Value);
groupCtr++;
int captureCtr = 0;
foreach (Capture capture in group.Captures)
{
Console.WriteLine(" Capture {0}: {1}", captureCtr, capture.Value);
captureCtr++;
}
}
}
}
}
// The example displays the following output:
// The match: This is the first sentence.
// Group 0: This is the first sentence.
// Capture 0: This is the first sentence.
// The match: Is it the beginning of a literary masterpiece?
// Group 0: Is it the beginning of a literary masterpiece?
// Capture 0: Is it the beginning of a literary masterpiece?
// The match: I think not.
// Group 0: I think not.
// Capture 0: I think not.
// The match: Instead, it is a nonsensical paragraph.
// Group 0: Instead, it is a nonsensical paragraph.
// Capture 0: Instead, it is a nonsensical paragraph.
Imports System.Text.RegularExpressions
Module Explicit2Example
Public Sub Main()
Dim input As String = "This is the first sentence. Is it the beginning " +
"of a literary masterpiece? I think not. Instead, " +
"it is a nonsensical paragraph."
Dim pattern As String = "(?n)\b\(?((?>\w+),?\s?)+[\.!?]\)?"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("The match: {0}", match.Value)
Dim groupCtr As Integer = 0
For Each group As Group In match.Groups
Console.WriteLine(" Group {0}: {1}", groupCtr, group.Value)
groupCtr += 1
Dim captureCtr As Integer = 0
For Each capture As Capture In group.Captures
Console.WriteLine(" Capture {0}: {1}", captureCtr, capture.Value)
captureCtr += 1
Next
Next
Next
End Sub
End Module
' The example displays the following output:
' The match: This is the first sentence.
' Group 0: This is the first sentence.
' Capture 0: This is the first sentence.
' The match: Is it the beginning of a literary masterpiece?
' Group 0: Is it the beginning of a literary masterpiece?
' Capture 0: Is it the beginning of a literary masterpiece?
' The match: I think not.
' Group 0: I think not.
' Capture 0: I think not.
' The match: Instead, it is a nonsensical paragraph.
' Group 0: Instead, it is a nonsensical paragraph.
' Capture 0: Instead, it is a nonsensical paragraph.
Abschließend können Sie mit dem Inlinegruppenelement (?n:)
automatische Erfassungen gruppenweise unterdrücken. Im folgenden Beispiel wird das vorherige Muster geändert, sodass unbenannte Erfassungen in der äußeren Gruppe ((?>\w+),?\s?)
unterdrückt werden. Beachten Sie, dass dadurch auch unbenannte Erfassungen in der inneren Gruppe unterdrückt werden.
using System;
using System.Text.RegularExpressions;
public class Explicit3Example
{
public static void Main()
{
string input = "This is the first sentence. Is it the beginning " +
"of a literary masterpiece? I think not. Instead, " +
"it is a nonsensical paragraph.";
string pattern = @"\b\(?(?n:(?>\w+),?\s?)+[\.!?]\)?";
foreach (Match match in Regex.Matches(input, pattern))
{
Console.WriteLine("The match: {0}", match.Value);
int groupCtr = 0;
foreach (Group group in match.Groups)
{
Console.WriteLine(" Group {0}: {1}", groupCtr, group.Value);
groupCtr++;
int captureCtr = 0;
foreach (Capture capture in group.Captures)
{
Console.WriteLine(" Capture {0}: {1}", captureCtr, capture.Value);
captureCtr++;
}
}
}
}
}
// The example displays the following output:
// The match: This is the first sentence.
// Group 0: This is the first sentence.
// Capture 0: This is the first sentence.
// The match: Is it the beginning of a literary masterpiece?
// Group 0: Is it the beginning of a literary masterpiece?
// Capture 0: Is it the beginning of a literary masterpiece?
// The match: I think not.
// Group 0: I think not.
// Capture 0: I think not.
// The match: Instead, it is a nonsensical paragraph.
// Group 0: Instead, it is a nonsensical paragraph.
// Capture 0: Instead, it is a nonsensical paragraph.
Imports System.Text.RegularExpressions
Module Explicit3Example
Public Sub Main()
Dim input As String = "This is the first sentence. Is it the beginning " +
"of a literary masterpiece? I think not. Instead, " +
"it is a nonsensical paragraph."
Dim pattern As String = "\b\(?(?n:(?>\w+),?\s?)+[\.!?]\)?"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("The match: {0}", match.Value)
Dim groupCtr As Integer = 0
For Each group As Group In match.Groups
Console.WriteLine(" Group {0}: {1}", groupCtr, group.Value)
groupCtr += 1
Dim captureCtr As Integer = 0
For Each capture As Capture In group.Captures
Console.WriteLine(" Capture {0}: {1}", captureCtr, capture.Value)
captureCtr += 1
Next
Next
Next
End Sub
End Module
' The example displays the following output:
' The match: This is the first sentence.
' Group 0: This is the first sentence.
' Capture 0: This is the first sentence.
' The match: Is it the beginning of a literary masterpiece?
' Group 0: Is it the beginning of a literary masterpiece?
' Capture 0: Is it the beginning of a literary masterpiece?
' The match: I think not.
' Group 0: I think not.
' Capture 0: I think not.
' The match: Instead, it is a nonsensical paragraph.
' Group 0: Instead, it is a nonsensical paragraph.
' Capture 0: Instead, it is a nonsensical paragraph.
Kompilierte reguläre Ausdrücke
Hinweis
Verwenden Sie nach Möglichkeit die quellgenerierten regulären Ausdrücke, anstatt reguläre Ausdrücke mithilfe der RegexOptions.Compiled-Option zu kompilieren. Die Quellgenerierung kann dazu beitragen, dass Ihre App schneller gestartet wird, schneller ausgeführt wird und besser gekürzt werden kann. Informationen dazu, wann die Quellgenerierung möglich ist, finden Sie unter Verwendung.
Standardmäßig werden reguläre Ausdrücke in .NET interpretiert. Wenn ein Regex-Objekt instanziiert oder eine statische Regex-Methode aufgerufen wird, wird das Muster eines regulären Ausdrucks in einen Satz benutzerdefinierter Opcodes analysiert, und ein Interpreter führt den regulären Ausdruck mithilfe dieser Opcodes aus. Dabei wird ein Kompromiss eingegangen: Der Aufwand für die Initialisierung der Engine für reguläre Ausdrücke wird auf Kosten der Laufzeitleistung minimiert.
Sie können kompilierte statt interpretierter regulärer Ausdrücke mit der RegexOptions.Compiled-Option verwenden. Wenn in diesem Fall ein Muster an die Engine für reguläre Ausdrücke übergeben wird, wird es in einen Satz von Vorgangscodes geparst und dann in CIL (Common Intermediate Language) konvertiert, sodass es direkt an die Common Language Runtime übergeben werden kann. Kompilierte reguläre Ausdrücke maximieren die Laufzeitleistung auf Kosten der Initialisierungszeit.
Hinweis
Ein regulärer Ausdruck kann nur kompiliert werden, indem der RegexOptions.Compiled-Wert an den options
-Parameter eines Regex-Klassenkonstruktors oder einer statischen Mustervergleichsmethode übergeben wird. Es besteht keine Verfügbarkeit als Inlineoption.
Sie können kompilierte reguläre Ausdrücke in Aufrufen von statischen regulären Ausdrücken und solchen für Instanzen verwenden. In statischen regulären Ausdrücken wird die RegexOptions.Compiled-Option an den options
-Parameter der Vergleichsmethode des regulären Ausdrucks übergeben. In regulären Ausdrucksinstanzen wird sie an den options
-Parameter des Regex-Klassenkonstruktors übergeben. In beiden Fällen führt dies zu einer besseren Leistung.
Diese Verbesserung der Leistung tritt jedoch nur unter den folgenden Bedingungen auf:
Ein Regex-Objekt, das einen bestimmten regulären Ausdruck darstellt, wird in mehreren Aufrufen regulärer Ausdrucksmustervergleichsmethoden verwendet.
Das Regex-Objekt darf den Gültigkeitsbereich nicht verlassen, daher kann es wiederverwendet werden.
Ein statischer regulärer Ausdruck wird in mehreren Aufrufen regulärer Ausdrucksmustervergleichsmethoden verwendet. (Die Leistungsverbesserung ist möglich, da reguläre in statischen Methodenaufrufen verwendete Ausdrücke von der Engine für reguläre Ausdrücke zwischengespeichert werden.)
Hinweis
Die RegexOptions.Compiled-Option steht in keinem Zusammenhang mit der Regex.CompileToAssembly-Methode, die eine zweckgebundene Assembly erstellt, die vordefinierte kompilierte reguläre Ausdrücke enthält.
Leerstellen ignorieren
Standardmäßig werden Leerstellen in einem Muster eines regulären Ausdrucks interpretiert. Die Engine für reguläre Ausdrücke sucht dann nach einem entsprechenden Leerstellenzeichen in der Eingabezeichenfolge. Daher sind die regulären Ausdrücke „\b\w+\s
“ und „\b\w+
“ weitgehend gleiche reguläre Ausdrücke. Außerdem wird das Nummernzeichen (#), wenn es in einem Muster eines regulären Ausdrucks gefunden wird, als Literalzeichen interpretiert und nach einer Übereinstimmung gesucht.
Die RegexOptions.IgnorePatternWhitespace-Option oder die x
-Inlineoption ändert dieses Standardverhalten wie folgt:
Leerstellen ohne Escapezeichen im Muster eines regulären Ausdrucks werden ignoriert. Um Teil eines Musters eines regulären Ausdrucks zu sein, müssen Leerstellenzeichen mit Escapezeichen versehen werden (z. B. „
\s
“ oder „\
“).Das Nummernzeichen (#) wird als Anfang eines Kommentars interpretiert, nicht als Literalzeichen. Der gesamte Text im Muster des regulären Ausdrucks vom Zeichen
#
bis entweder zum nächsten\n
-Zeichen oder bis zum Ende der Zeichenfolge wird als Kommentar interpretiert.
In den folgenden Fällen werden Leerzeichen in regulären Ausdrücken jedoch nicht ignoriert, auch wenn Sie die RegexOptions.IgnorePatternWhitespace-Option verwenden:
Leerzeichen in einer Zeichenklasse werden stets literal interpretiert. Der reguläre Ausdruck
[ .,;:]
findet z. B. ein einzelnes Leerstellenzeichen, Punkt, Komma, Semikolon oder einen Doppelpunkt.Leerzeichen sind innerhalb von in Klammern gesetzten Quantifizierern wie
{
n}
,{
n,}
und{
n,
m}
nicht zulässig. Das Muster eines regulären Ausdrucks\d{1, 3}
findet z. B. keine Übereinstimmung mit Ziffernsequenzen von einer bis zu drei Ziffern, da es ein Leerzeichen enthält.Leerzeichen sind in Zeichenfolgen, die Sprachelemente einleiten, nicht zulässig. Zum Beispiel:
Das Sprachelement
(?:
Teilausdruck)
stellt eine nicht erfassende Gruppe dar, und der(?:
-Teil des Elements darf keine eingebetteten Leerzeichen enthalten. Das Muster(? :
subexpression)
löst zur Laufzeit eine ArgumentException aus, da die Engine für reguläre Ausdrücke das Muster nicht analysieren kann und das Muster( ?:
subexpression)
findet keine Übereinstimmung zu subexpression.Das Sprachelement
\p{
Name}
, das für eine Unicode-Kategorie oder einen benannten Block steht, darf im\p{
-Teil des Elements kein eingebettetes Leerzeichen enthalten. Falls Sie trotzdem ein Leerzeichen einfügen, löst das Element zur Laufzeit eine ArgumentException aus.
Durch das Aktivieren dieser Option werden reguläre Ausdrücke vereinfacht, die oft schwierig zu analysieren und zu verstehen sind. Dadurch wird Lesbarkeit verbessert, und es wird möglich, einen regulären Ausdruck zu dokumentieren.
Im folgenden Beispiel wird das folgende Muster des regulären Ausdrucks definiert:
\b \(? ( (?>\w+) ,?\s? )+ [\.!?] \)? # Matches an entire sentence.
Dieses Muster ist dem im Abschnitt Nur explizite Erfassungen definierten Muster ähnlich, außer dass mithilfe der RegexOptions.IgnorePatternWhitespace-Option Musterleerzeichen ignoriert werden.
using System;
using System.Text.RegularExpressions;
public class Whitespace1Example
{
public static void Main()
{
string input = "This is the first sentence. Is it the beginning " +
"of a literary masterpiece? I think not. Instead, " +
"it is a nonsensical paragraph.";
string pattern = @"\b \(? ( (?>\w+) ,?\s? )+ [\.!?] \)? # Matches an entire sentence.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnorePatternWhitespace))
Console.WriteLine(match.Value);
}
}
// The example displays the following output:
// This is the first sentence.
// Is it the beginning of a literary masterpiece?
// I think not.
// Instead, it is a nonsensical paragraph.
Imports System.Text.RegularExpressions
Module Whitespace1Example
Public Sub Main()
Dim input As String = "This is the first sentence. Is it the beginning " +
"of a literary masterpiece? I think not. Instead, " +
"it is a nonsensical paragraph."
Dim pattern As String = "\b \(? ( (?>\w+) ,?\s? )+ [\.!?] \)? # Matches an entire sentence."
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnorePatternWhitespace)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
' This is the first sentence.
' Is it the beginning of a literary masterpiece?
' I think not.
' Instead, it is a nonsensical paragraph.
Im folgenden Beispiel wird die Inlineoption (?x)
verwendet, um Leerzeichen im Muster zu ignorieren.
using System;
using System.Text.RegularExpressions;
public class Whitespace2Example
{
public static void Main()
{
string input = "This is the first sentence. Is it the beginning " +
"of a literary masterpiece? I think not. Instead, " +
"it is a nonsensical paragraph.";
string pattern = @"(?x)\b \(? ( (?>\w+) ,?\s? )+ [\.!?] \)? # Matches an entire sentence.";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine(match.Value);
}
}
// The example displays the following output:
// This is the first sentence.
// Is it the beginning of a literary masterpiece?
// I think not.
// Instead, it is a nonsensical paragraph.
Imports System.Text.RegularExpressions
Module Whitespace2Example
Public Sub Main()
Dim input As String = "This is the first sentence. Is it the beginning " +
"of a literary masterpiece? I think not. Instead, " +
"it is a nonsensical paragraph."
Dim pattern As String = "(?x)\b \(? ( (?>\w+) ,?\s? )+ [\.!?] \)? # Matches an entire sentence."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
' This is the first sentence.
' Is it the beginning of a literary masterpiece?
' I think not.
' Instead, it is a nonsensical paragraph.
Rechts-nach-links-Modus
Standardmäßig sucht die Engine für reguläre Ausdrücke von links nach rechts. Sie können mit der Option RegexOptions.RightToLeft die Suchrichtung umkehren. Die Suche von rechts nach links startet automatisch bei der Position des letzten Zeichens der Zeichenfolge. Bei Mustervergleichsmethoden, die einen Anfangspositionsparameter enthalten, z. B. Regex.Match(String, Int32), ist die angegebene Anfangsposition der Index der am weitesten rechts stehenden Zeichenposition, bei der die Suche beginnt.
Hinweis
Der Skriptmodus "von rechts nach links" ist nur verfügbar, wenn der RegexOptions.RightToLeft-Wert an den options
-Parameter eines Regex-Klassenkonstruktors oder einer statischen Mustervergleichsmethode übergeben wird. Es besteht keine Verfügbarkeit als Inlineoption.
Beispiel
Der reguläre Ausdruck \bb\w+\s
findet Wörter mit zwei oder mehr Zeichen, die mit dem Buchstaben „b“ beginnen und auf die ein Leerzeichen folgt. Im folgenden Beispiel besteht die Eingabezeichenfolge aus drei Wörtern, die ein oder mehrere "b"-Zeichen enthalten. Das erste und zweite Wort beginnen mit „b“ und das dritte Wort endet mit „b“. Wie die Ausgabe der Suche von rechts nach links zeigt, entsprechen nur das erste und zweite Wort dem regulären Ausdruck, wobei das zweite Wort zuerst gefunden wird.
using System;
using System.Text.RegularExpressions;
public class RTL1Example
{
public static void Main()
{
string pattern = @"\bb\w+\s";
string input = "build band tab";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.RightToLeft))
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index);
}
}
// The example displays the following output:
// 'band ' found at position 6.
// 'build ' found at position 0.
Imports System.Text.RegularExpressions
Module RTL1Example
Public Sub Main()
Dim pattern As String = "\bb\w+\s"
Dim input As String = "build band tab"
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.RightToLeft)
Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
End Sub
End Module
' The example displays the following output:
' 'band ' found at position 6.
' 'build ' found at position 0.
Auswertungsreihenfolge
Die Option RegexOptions.RightToLeft ändert die Suchrichtung und kehrt auch die Reihenfolge um, in der das Muster des regulären Ausdrucks ausgewertet wird. Bei einer Suche von rechts nach links wird das Suchmuster von rechts nach links gelesen. Diese Unterscheidung ist wichtig, da sie sich auf Aspekte wie Erfassungsgruppen und Rückverweise auswirken kann. Beispielsweise findet der Ausdruck Regex.Match("abcabc", @"\1(abc)", RegexOptions.RightToLeft)
eine Übereinstimmung abcabc
, aber bei einer Suche von links nach rechts (Regex.Match("abcabc", @"\1(abc)", RegexOptions.None)
) wird keine Übereinstimmung gefunden. Das liegt daran, dass das Element (abc)
vor dem nummerierten Element der Erfassungsgruppe (\1
) ausgewertet werden muss, damit eine Übereinstimmung gefunden werden kann.
Lookahead- und Lookbehindassertionen
Die Position einer Übereinstimmung für eine Lookahead- ((?=subexpression)
) oder Lookbehindassertion ((?<=subexpression)
) ändert sich nicht bei einer Suche von rechts nach links. Die Lookaheadassertionen suchen rechts von der aktuellen Abgleichsposition, die Lookbehindassertionen suchen links von der aktuellen Abgleichsposition.
Tipp
Unabhängig davon, ob eine Suche von rechts nach links erfolgt oder nicht, werden Suchabfragen mithilfe einer Suche von rechts nach links ab der aktuellen Abgleichsposition implementiert.
Der reguläre Ausdruck (?<=\d{1,2}\s)\w+,\s\d{4}
testet z. B. mithilfe der Lookbehindassertion auf ein Datum, das einem Monatsnamen vorausgeht. Der reguläre Ausdruck gleicht dann Monat und Jahr ab. Informationen zu Lookahead- und Lookbehindassertionen finden Sie unter Gruppierungskonstrukte.
using System;
using System.Text.RegularExpressions;
public class RTL2Example
{
public static void Main()
{
string[] inputs = { "1 May, 1917", "June 16, 2003" };
string pattern = @"(?<=\d{1,2}\s)\w+,\s\d{4}";
foreach (string input in inputs)
{
Match match = Regex.Match(input, pattern, RegexOptions.RightToLeft);
if (match.Success)
Console.WriteLine("The date occurs in {0}.", match.Value);
else
Console.WriteLine("{0} does not match.", input);
}
}
}
// The example displays the following output:
// The date occurs in May, 1917.
// June 16, 2003 does not match.
Imports System.Text.RegularExpressions
Module RTL2Example
Public Sub Main()
Dim inputs() As String = {"1 May, 1917", "June 16, 2003"}
Dim pattern As String = "(?<=\d{1,2}\s)\w+,\s\d{4}"
For Each input As String In inputs
Dim match As Match = Regex.Match(input, pattern, RegexOptions.RightToLeft)
If match.Success Then
Console.WriteLine("The date occurs in {0}.", match.Value)
Else
Console.WriteLine("{0} does not match.", input)
End If
Next
End Sub
End Module
' The example displays the following output:
' The date occurs in May, 1917.
' June 16, 2003 does not match.
Das Muster für reguläre Ausdrücke ist wie in der folgenden Tabelle gezeigt definiert.
Muster | Beschreibung |
---|---|
(?<=\d{1,2}\s) |
Dem Anfang der Übereinstimmung müssen eine oder zwei von einem Leerzeichen gefolgte Dezimalstellen vorangestellt sein. |
\w+ |
Übereinstimmung mit mindestens einem Wortzeichen. |
, |
Abgleichen eines Kommazeichens. |
\s |
Entsprechung für ein Leerraumzeichen finden. |
\d{4} |
Entsprechung für vier Dezimalstellen finden. |
ECMAScript-Vergleichsverhalten
Standardmäßig verwendet die Engine für reguläre Ausdrücke das kanonische Verhalten, wenn ein Muster eines regulären Ausdrucks mit dem Eingabetext verglichen wird. Sie können jedoch die Engine für reguläre Ausdrücke anweisen, das ECMAScript-Vergleichsverhalten zu verwenden, indem Sie die RegexOptions.ECMAScript-Option angeben.
Hinweis
ECMAScript-kompatibles Verhalten ist nur verfügbar, wenn der RegexOptions.ECMAScript-Wert an den options
-Parameter eines Regex-Klassenkonstruktors oder einer statischen Mustervergleichsmethode übergeben wird. Es besteht keine Verfügbarkeit als Inlineoption.
Die RegexOptions.ECMAScript-Option kann nur mit den Optionen RegexOptions.IgnoreCase und RegexOptions.Multiline kombiniert werden. Die Verwendung einer die oft ausgegebene Befehlszeilen anderen Option in einem regulären Ausdruck führt zu einer ArgumentOutOfRangeException.
Das Verhalten von ECMAScript und kanonischen regulären Ausdrücke unterscheidet sich in drei Bereichen: Zeichenklassensyntax, bei Selbstverweisen von Erfassungsgruppen sowie bei der Interpretation von Oktalwerten und Rückverweisen.
Zeichenklassensyntax. Da kanonische reguläre Ausdrücke im Gegensatz zu ECMAScript Unicode unterstützen, weisen Zeichenklassen in ECMAScript eine beschränktere Syntax auf, und einige Zeichenklassensprachelemente haben eine andere Bedeutung. ECMAScript unterstützt z. B. keine Sprachelemente wie die Kategorie- oder Blockelemente
\p
und\P
von Unicode. Entsprechend ist das\w
-Element, das einem Wortzeichen entspricht, äquivalent zur[a-zA-Z_0-9]
-Zeichenklasse beim Verwenden von ECMAScript bzw. äquivalent zu[\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}\p{Lm}]
beim Verwenden des kanonischen Verhaltens. Weitere Informationen finden Sie unter Zeichenklassen in regulären Ausdrücken.Im folgenden Beispiel wird der Unterschied zwischen kanonischen und ECMAScript-Mustervergleichen veranschaulicht. Dabei wird ein regulärer Ausdruck,
\b(\w+\s*)+
, definiert, der eine Entsprechung für Wörter findet, denen Leerstellenzeichen folgen. Die Eingabe besteht aus zwei Zeichenfolgen, einer mit dem lateinischen Zeichensatz und einer mit dem kyrillischen Zeichensatz. Wie die Ausgabe zeigt, findet der Aufruf der Regex.IsMatch(String, String, RegexOptions)-Methode, die ECMAScript verwendet, keine Entsprechung für die kyrillischen Wörter, wohingegen der Methodenaufruf, der einen kanonischen Vergleich verwendet, eine Entsprechung für diese Wörter findet.using System; using System.Text.RegularExpressions; public class EcmaScriptExample { public static void Main() { string[] values = { "целый мир", "the whole world" }; string pattern = @"\b(\w+\s*)+"; foreach (var value in values) { Console.Write("Canonical matching: "); if (Regex.IsMatch(value, pattern)) Console.WriteLine("'{0}' matches the pattern.", value); else Console.WriteLine("{0} does not match the pattern.", value); Console.Write("ECMAScript matching: "); if (Regex.IsMatch(value, pattern, RegexOptions.ECMAScript)) Console.WriteLine("'{0}' matches the pattern.", value); else Console.WriteLine("{0} does not match the pattern.", value); Console.WriteLine(); } } } // The example displays the following output: // Canonical matching: 'целый мир' matches the pattern. // ECMAScript matching: целый мир does not match the pattern. // // Canonical matching: 'the whole world' matches the pattern. // ECMAScript matching: 'the whole world' matches the pattern.
Imports System.Text.RegularExpressions Module Ecma1Example Public Sub Main() Dim values() As String = {"целый мир", "the whole world"} Dim pattern As String = "\b(\w+\s*)+" For Each value In values Console.Write("Canonical matching: ") If Regex.IsMatch(value, pattern) Then Console.WriteLine("'{0}' matches the pattern.", value) Else Console.WriteLine("{0} does not match the pattern.", value) End If Console.Write("ECMAScript matching: ") If Regex.IsMatch(value, pattern, RegexOptions.ECMAScript) Then Console.WriteLine("'{0}' matches the pattern.", value) Else Console.WriteLine("{0} does not match the pattern.", value) End If Console.WriteLine() Next End Sub End Module ' The example displays the following output: ' Canonical matching: 'целый мир' matches the pattern. ' ECMAScript matching: целый мир does not match the pattern. ' ' Canonical matching: 'the whole world' matches the pattern. ' ECMAScript matching: 'the whole world' matches the pattern.
Auf sich selbst verweisende Erfassungsgruppen. Eine Aufzeichnungsklasse für einen regulären Ausdruck mit einem Rückverweis auf sich selbst muss mit jeder Aufzeichnungsiteration aktualisiert werden. Wie das folgende Beispiel zeigt, aktiviert diese Funktion den regulären Ausdruck
((a+)(\1) ?)+
, um eine Entsprechung für die Eingabezeichenfolge " aa aaaa aaaaaa " zu finden, wenn ECMAScript verwendet wird, jedoch nicht, wenn kanonische Vergleiche verwendet werden.using System; using System.Text.RegularExpressions; public class EcmaScript2Example { static string pattern; public static void Main() { string input = "aa aaaa aaaaaa "; pattern = @"((a+)(\1) ?)+"; // Match input using canonical matching. AnalyzeMatch(Regex.Match(input, pattern)); // Match input using ECMAScript. AnalyzeMatch(Regex.Match(input, pattern, RegexOptions.ECMAScript)); } private static void AnalyzeMatch(Match m) { if (m.Success) { Console.WriteLine("'{0}' matches {1} at position {2}.", pattern, m.Value, m.Index); int grpCtr = 0; foreach (Group grp in m.Groups) { Console.WriteLine(" {0}: '{1}'", grpCtr, grp.Value); grpCtr++; int capCtr = 0; foreach (Capture cap in grp.Captures) { Console.WriteLine(" {0}: '{1}'", capCtr, cap.Value); capCtr++; } } } else { Console.WriteLine("No match found."); } Console.WriteLine(); } } // The example displays the following output: // No match found. // // '((a+)(\1) ?)+' matches aa aaaa aaaaaa at position 0. // 0: 'aa aaaa aaaaaa ' // 0: 'aa aaaa aaaaaa ' // 1: 'aaaaaa ' // 0: 'aa ' // 1: 'aaaa ' // 2: 'aaaaaa ' // 2: 'aa' // 0: 'aa' // 1: 'aa' // 2: 'aa' // 3: 'aaaa ' // 0: '' // 1: 'aa ' // 2: 'aaaa '
Imports System.Text.RegularExpressions Module Ecma2Example Dim pattern As String Public Sub Main() Dim input As String = "aa aaaa aaaaaa " pattern = "((a+)(\1) ?)+" ' Match input using canonical matching. AnalyzeMatch(Regex.Match(input, pattern)) ' Match input using ECMAScript. AnalyzeMatch(Regex.Match(input, pattern, RegexOptions.ECMAScript)) End Sub Private Sub AnalyzeMatch(m As Match) If m.Success Then Console.WriteLine("'{0}' matches {1} at position {2}.", pattern, m.Value, m.Index) Dim grpCtr As Integer = 0 For Each grp As Group In m.Groups Console.WriteLine(" {0}: '{1}'", grpCtr, grp.Value) grpCtr += 1 Dim capCtr As Integer = 0 For Each cap As Capture In grp.Captures Console.WriteLine(" {0}: '{1}'", capCtr, cap.Value) capCtr += 1 Next Next Else Console.WriteLine("No match found.") End If Console.WriteLine() End Sub End Module ' The example displays the following output: ' No match found. ' ' '((a+)(\1) ?)+' matches aa aaaa aaaaaa at position 0. ' 0: 'aa aaaa aaaaaa ' ' 0: 'aa aaaa aaaaaa ' ' 1: 'aaaaaa ' ' 0: 'aa ' ' 1: 'aaaa ' ' 2: 'aaaaaa ' ' 2: 'aa' ' 0: 'aa' ' 1: 'aa' ' 2: 'aa' ' 3: 'aaaa ' ' 0: '' ' 1: 'aa ' ' 2: 'aaaa '
Der reguläre Ausdruck wird entsprechend der Darstellung in der folgenden Tabelle definiert:
Muster Beschreibung (a+) Entspricht einem oder mehreren Vorkommen des Buchstabens "a". Dies ist die zweite Erfassungsgruppe. (\1) Entspricht der Teilzeichenfolge, die von der ersten Erfassungsgruppe erfasst wurde. Dies ist die dritte Erfassungsgruppe. ? Entspricht keinem oder einem Leerzeichen. ((a+)(\1) ?)+ Entspricht mindestens einem "a", ein- oder mehrmals gefolgt von einer Zeichenfolge, die der ersten Erfassungsgruppe entspricht, und keinem oder mehr Leerzeichen. Dies ist die erste Erfassungsgruppe. Auflösung von Zweideutigkeiten zwischen Oktalescapezeichen und Rückverweisen. Die folgende Tabelle fasst die Unterschiede zwischen der Oktal- und der Rückverweisinterpretation durch kanonische reguläre Ausdrücke und reguläre ECMAScript-Ausdrücke zusammen.
Regulärer Ausdruck Kanonisches Verhalten ECMAScript-Verhalten \0
gefolgt von 0 bis 2 OktalziffernAls Oktalwert interpretieren. Zum Beispiel wird \044
immer als Oktalwert interpretiert und bedeutet "$".Gleiches Verhalten. \
gefolgt von einer Ziffer zwischen 1 und 9 ohne nachfolgende DezimalziffernAls Rückverweis interpretieren. Zum Beispiel bedeutet \9
immer Rückverweis 9, auch wenn keine Erfassungsgruppe 9 vorhanden ist. Wenn die Aufzeichnungsgruppe nicht vorhanden ist, löst der Parser für den regulären Ausdruck eine ArgumentException aus.Wenn eine Erfassungsgruppe einer einzigen Dezimalziffer vorhanden ist, wird ein Rückverweis auf diese Ziffer ausgeführt. Andernfalls wird der Wert als Literal interpretiert. \
gefolgt von einer Ziffer zwischen 1 und 9 mit nachfolgenden DezimalziffernZiffern als Dezimalwert interpretieren. Wenn diese Erfassungsgruppe vorhanden ist, wird der Ausdruck als Rückverweis interpretiert.
Ansonsten werden die vorangestellten Oktalziffern bis zur Oktalzahl 377 interpretiert. Das bedeutet, dass nur die unteren 8 Bits des Werts berücksichtigt werden. Verbleibende Ziffern als Literale interpretieren. Beispiel: Wenn im Ausdruck\3000
die Erfassungsgruppe 300 vorhanden ist, wird der Ausdruck als Rückverweis 300 interpretiert. Wenn die Erfassungsgruppe 300 nicht vorhanden ist, wird er als Oktalzahl 300 gefolgt von 0 interpretiert.Als Rückverweis interpretieren, indem so viele Ziffern wie möglich in einen Dezimalwert konvertiert werden, der auf eine Erfassung verweisen kann. Wenn keine Ziffern konvertiert werden können, wird der Ausdruck als Oktalzahl unter Verwendung der ersten Oktalziffern bis zu Oktalzahl 377 interpretiert, und die restlichen Ziffern werden als Literale interpretiert.
Vergleichen mithilfe der invarianten Kultur
Standardmäßig verwendet die Engine für reguläre Ausdrücke bei Vergleichen ohne Berücksichtigung der Groß- und Kleinschreibung die Groß-/Kleinschreibungskonventionen der aktuellen Kultur, um äquivalente Groß- und Kleinbuchstaben zu ermitteln.
Dieses Verhalten ist jedoch für einige Typen von Vergleichen unerwünscht, insbesondere wenn Benutzereingaben mit Namen von Systemressourcen wie Kennwörtern, Dateien oder URLs verglichen werden. Das folgende Beispiel illustriert ein solches Szenario. Der Code ist dazu gedacht, den Zugriff auf jede Ressource zu blockieren, deren URL mit FILE:// beginnt. Der reguläre Ausdruck sucht nach einer Übereinstimmung ohne Beachtung der Groß-/Kleinschreibung mit der Zeichenfolge unter Verwendung des regulären Ausdrucks $FILE://
. Wenn die aktuelle Systemkultur jedoch „tr-TR (Türkisch-Türkei)“ ist, ist „I“ nicht der entsprechende Großbuchstabe zu „i“. Als Ergebnis gibt der Aufruf der Regex.IsMatch-Methode false
zurück, und der Zugriff auf die Datei wird zugelassen.
CultureInfo defaultCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR");
string input = "file://c:/Documents.MyReport.doc";
string pattern = "FILE://";
Console.WriteLine("Culture-sensitive matching ({0} culture)...",
Thread.CurrentThread.CurrentCulture.Name);
if (Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase))
Console.WriteLine("URLs that access files are not allowed.");
else
Console.WriteLine("Access to {0} is allowed.", input);
Thread.CurrentThread.CurrentCulture = defaultCulture;
// The example displays the following output:
// Culture-sensitive matching (tr-TR culture)...
// Access to file://c:/Documents.MyReport.doc is allowed.
Dim defaultCulture As CultureInfo = Thread.CurrentThread.CurrentCulture
Thread.CurrentThread.CurrentCulture = New CultureInfo("tr-TR")
Dim input As String = "file://c:/Documents.MyReport.doc"
Dim pattern As String = "$FILE://"
Console.WriteLine("Culture-sensitive matching ({0} culture)...",
Thread.CurrentThread.CurrentCulture.Name)
If Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase) Then
Console.WriteLine("URLs that access files are not allowed.")
Else
Console.WriteLine("Access to {0} is allowed.", input)
End If
Thread.CurrentThread.CurrentCulture = defaultCulture
' The example displays the following output:
' Culture-sensitive matching (tr-TR culture)...
' Access to file://c:/Documents.MyReport.doc is allowed.
Hinweis
Weitere Informationen zu Zeichenfolgenvergleichen, bei denen die Groß-/Kleinschreibung beachtet wird und die die invariante Kultur verwenden, finden Sie unter Empfohlene Vorgehensweisen für die Verwendung von Zeichenfolgen.
Statt die Vergleiche von der aktuellen Kultur zu verwenden, bei denen nicht zwischen Groß- und Kleinschreibung unterschieden wird, können Sie die RegexOptions.CultureInvariant-Option angeben, um kulturelle Unterschiede in der Sprache zu ignorieren und die Konventionen der invarianten Kultur zu verwenden.
Hinweis
Vergleiche mit der invarianten Kultur sind nur möglich, indem der RegexOptions.CultureInvariant-Wert an den options
-Parameter eines Regex-Klassenkonstruktors oder einer statischen Mustervergleichsmethode übergeben wird. Es besteht keine Verfügbarkeit als Inlineoption.
Das folgende Beispiel ist mit dem vorherigen Beispiel identisch, abgesehen davon, dass die statische Regex.IsMatch(String, String, RegexOptions)-Methode mit Optionen aufgerufen wird, die RegexOptions.CultureInvariant enthalten. Auch wenn die aktuelle Kultur auf „Türkisch (Türkei)“ festgelegt ist, kann die Engine für reguläre Ausdrücke „FILE“ und „file“ erfolgreich zuordnen und den Zugriff auf die Dateiressource blockieren.
CultureInfo defaultCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR");
string input = "file://c:/Documents.MyReport.doc";
string pattern = "FILE://";
Console.WriteLine("Culture-insensitive matching...");
if (Regex.IsMatch(input, pattern,
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
Console.WriteLine("URLs that access files are not allowed.");
else
Console.WriteLine("Access to {0} is allowed.", input);
Thread.CurrentThread.CurrentCulture = defaultCulture;
// The example displays the following output:
// Culture-insensitive matching...
// URLs that access files are not allowed.
Dim defaultCulture As CultureInfo = Thread.CurrentThread.CurrentCulture
Thread.CurrentThread.CurrentCulture = New CultureInfo("tr-TR")
Dim input As String = "file://c:/Documents.MyReport.doc"
Dim pattern As String = "$FILE://"
Console.WriteLine("Culture-insensitive matching...")
If Regex.IsMatch(input, pattern,
RegexOptions.IgnoreCase Or RegexOptions.CultureInvariant) Then
Console.WriteLine("URLs that access files are not allowed.")
Else
Console.WriteLine("Access to {0} is allowed.", input)
End If
Thread.CurrentThread.CurrentCulture = defaultCulture
' The example displays the following output:
' Culture-insensitive matching...
' URLs that access files are not allowed.
Nicht zurückverfolgender Modus
Standardmäßig verwendet die RegEx-Engine von .NET die Rückverfolgung, um Übereinstimmungen mit einem Muster zu finden. Eine Rückverfolgungs-Engine ist eine Engine, die versucht, Übereinstimmungen mit einem Muster zu finden. Wenn dies zu keinen Ergebnissen führt, kehrt sie zurück und sucht nach Übereinstimmungen mit einem anderen Muster usw. Eine Rückverfolgungs-Engine ist für die gängigen Fälle sehr schnell, wird jedoch langsamer, wenn die Anzahl der Mustervarianten zunimmt. Dies kann zu einer katastrophalen Rückverfolgung führen. Die Option RegexOptions.NonBacktracking , die in .NET 7 eingeführt wurde, verwendet keine Rückverfolgung und vermeidet dieses Worst-Case-Szenario. Das Ziel ist es, unabhängig von der gesuchten Eingabe ein konstant gutes Verhalten zu liefern.
Die RegexOptions.NonBacktracking-Option unterstützt nicht alle Funktionen, die von den anderen integrierten Engines unterstützt werden. Insbesondere kann die Option nicht in Verbindung mit RegexOptions.RightToLeft oder RegexOptions.ECMAScript verwendet werden. Außerdem sind die folgenden Konstrukte in Mustern nicht zulässig:
- Atomische Gruppen
- Rückverweise
- Ausgleichsgruppen
- Bedingungen
- Lookarounds
- Startanker (
\G
)
RegexOptions.NonBacktracking weist auch einen feinen Unterschied in Bezug auf die Ausführung auf. Wenn sich eine Erfassungsgruppe in einer Schleife befindet, geben die meisten RegEx-Engines (nicht .NET) nur den letzten übereinstimmenden Wert für diese Erfassung zurück. Die RegEx-Engine von NET verfolgt jedoch alle Werte nach, die innerhalb einer Schleife erfasst werden, und ermöglicht den Zugriff darauf. Die RegexOptions.NonBacktracking-Option verhält sich wie die meisten anderen RegEx-Implementierungen und unterstützt nur die Bereitstellung der endgültigen Erfassung.
Weitere Informationen zur Rückverfolgung finden Sie unter Rückverfolgung in regulären Ausdrücken.