Opzioni di espressioni regolari
Per impostazione predefinita, il confronto di una stringa di input con qualsiasi carattere letterale in un criterio di ricerca di espressioni regolari prevede la distinzione tra maiuscole e minuscole. Gli spazi vuoti in un criterio di ricerca di espressioni regolari vengono interpretati come caratteri di spazi vuoti letterali e i gruppi di acquisizione in un'espressione regolare sono denominati in modo sia implicito che esplicito. È possibile modificare questi e molti altri aspetti del comportamento predefinito delle espressioni regolari specificando le relative opzioni. Alcune di queste opzioni, elencate nella tabella seguente, possono essere incluse inline come parte del criterio di ricerca di espressioni regolari o in alternativa fornite a un costruttore della classe System.Text.RegularExpressions.Regex o a un metodo statico dei criteri di ricerca come valore di enumerazione System.Text.RegularExpressions.RegexOptions.
MembroRegexOptions |
Carattere inline | Effetto | Ulteriori informazioni |
---|---|---|---|
None | Non disponibile | Usare il comportamento predefinito. | Opzioni predefinite |
IgnoreCase | i |
Usa la corrispondenza che non fa distinzione tra maiuscole e minuscole. | Corrispondenza senza distinzione tra maiuscole e minuscole |
Multiline | m |
Usare la modalità multiriga, in cui ^ e $ indicano l'inizio e la fine di una riga, anziché l'inizio e la fine della stringa di input. |
Modalità multiriga |
Singleline | s |
Usa la modalità a riga singola, in cui il punto (.) corrisponde a qualsiasi carattere anziché a tutti i caratteri tranne \n . |
Modalità a riga singola |
ExplicitCapture | n |
Non acquisire gruppi senza nome. Le uniche acquisizioni valide sono i gruppi denominati o numerati in modo esplicito in formato (?< nome> sottoespressione) . |
Solo acquisizioni esplicite |
Compiled | Non disponibile | Compila l'espressione regolare in un assembly. | Espressioni regolari compilate |
IgnorePatternWhitespace | x |
Esclude gli spazi vuoti senza caratteri di escape nel criterio e abilita i commenti dopo un simbolo di cancelletto (# ). |
Ignora spazi vuoti |
RightToLeft | Non disponibile | Modifica la direzione di ricerca. La ricerca viene eseguita da destra verso sinistra, anziché da sinistra verso destra. | Modalità da destra a sinistra |
ECMAScript | Non disponibile | Abilita un comportamento conforme a ECMAScript per l'espressione. | Comportamento di corrispondenza ECMAScript |
CultureInvariant | Non disponibile | Ignora le differenze di cultura nella lingua. | Confronto usando le impostazioni di cultura inglese non dipendenti da paese/area geografica |
NonBacktracking | Non disponibile | Abbinare usando un approccio che eviti il backtracking e garantisca l'elaborazione in tempo lineare nella lunghezza dell'input. Disponibile in .NET 7 e versioni successive. | Modalità non backtracking |
Specificare le opzioni
È possibile specificare le opzioni per le espressioni regolari in tre modi:
Nel parametro
options
di un costruttore della classe System.Text.RegularExpressions.Regex o di un metodo statico (Shared
in Visual Basic) dei criteri di ricerca, ad esempio Regex(String, RegexOptions) o Regex.Match(String, String, RegexOptions). Il parametrooptions
è una combinazione OR bit per bit dei valori enumerati System.Text.RegularExpressions.RegexOptions.Quando vengono specificate le opzioni per un'istanza di Regex usando il parametro
options
di un costruttore di classe, le opzioni vengono assegnate alla proprietà System.Text.RegularExpressions.RegexOptions. Tuttavia, la proprietà System.Text.RegularExpressions.RegexOptions non rispecchia le opzioni inline nel criterio di ricerca di espressioni regolari stesso.Di seguito ne viene illustrato un esempio. Il parametro
options
del metodo Regex.Match(String, String, RegexOptions) viene usato per abilitare la corrispondenza senza distinzione tra maiuscole e minuscole e per ignorare gli spazi vuoti nel criterio durante l'identificazione delle parole che iniziano con la lettera "d".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.
Applicando le opzioni inline in un criterio di ricerca di espressioni regolari con la sintassi
(?imnsx-imnsx)
. L'opzione si applica al criterio dal punto in cui viene definita fino alla fine del criterio oppure fino al punto in cui viene annullata da un'altra opzione inline. Si noti che la proprietà System.Text.RegularExpressions.RegexOptions di un'istanza di Regex non rispecchia queste opzioni inline. Per altre informazioni, vedere l'argomento Costrutti vari.Di seguito ne viene illustrato un esempio. Le opzioni online vengono usate per abilitare la corrispondenza senza distinzione tra maiuscole e minuscole e per ignorare gli spazi vuoti nel criterio durante l'identificazione delle parole che iniziano con la lettera "d".
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.
Applicando opzioni inline in un particolare costrutto di raggruppamento in un criterio di ricerca di espressioni regolari con la sintassi
(?imnsx-imnsx:
sottoespressione)
. Nessun segno prima di un set di opzioni attiva il set. Un segno meno prima di un set di opzioni disattiva il set.?
è una parte fissa della sintassi del costrutto di linguaggio richiesta se vengono abilitate o disabilitate funzioni. L'opzione si applica solo al gruppo specificato. Per altre informazioni, vedere Costrutti di raggruppamento.Di seguito ne viene illustrato un esempio. Le opzioni online vengono usate in un costrutto di raggruppamento per abilitare la corrispondenza senza distinzione tra maiuscole e minuscole e per ignorare gli spazi vuoti nel criterio durante l'identificazione delle parole che iniziano con la lettera "d".
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.
Se le opzioni vengono specificate inline, un segno meno (-
) prima di un'opzione o di un set di opzioni consente di disattivare tali opzioni. Ad esempio, il costrutto inline (?ix-ms)
attiva le opzioni RegexOptions.IgnoreCase e RegexOptions.IgnorePatternWhitespace e disattiva le opzioni RegexOptions.Multiline e RegexOptions.Singleline. Per impostazione predefinita, tutte le opzioni di espressioni regolari sono disattivate.
Nota
In caso di conflitto tra le opzioni di espressione regolare specificate nel parametro options
di un costruttore o di una chiamata a metodo e le opzioni specificate inline in un criterio di ricerca di espressioni regolari, vengono usate le opzioni inline.
Le cinque opzioni di espressione regolare seguenti possono essere impostate sia con il parametro options che inline:
Le cinque opzioni di espressione regolare seguenti possono essere impostate usando il parametro options
, ma non inline:
Determinare le opzioni
È possibile determinare le opzioni fornite a un oggetto Regex al momento della creazione dell'istanza recuperando il valore della proprietà Regex.Options di sola lettura.
Per testare la presenza di qualsiasi opzione eccetto RegexOptions.None, eseguire un'operazione AND con il valore della proprietà Regex.Options e il valore RegexOptions desiderato. Testare quindi se il risultato corrisponde al valore RegexOptions. L'esempio seguente testa se l'opzione RegexOptions.IgnoreCase è stata impostata.
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
Per testare RegexOptions.None, determinare se il valore della proprietà Regex.Options sia uguale a RegexOptions.None, come illustrato nell'esempio seguente.
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
Nelle sezioni seguenti sono riportate le opzioni supportate dalle espressioni regolari in .NET.
Opzioni predefinite
L'opzione RegexOptions.None indica che non sono state specificate opzioni e che il motore delle espressioni regolari usa il comportamento predefinito. È incluso quanto segue:
Il criterio viene interpretato come canonico anziché come espressione regolare ECMAScript.
Il criterio di ricerca di espressioni regolari viene messo in corrispondenza nella stringa di input da sinistra verso destra.
Nei confronti viene fatta distinzione tra maiuscole e minuscole.
Gli elementi di linguaggio
^
e$
indicano l'inizio e la fine della stringa di input. La fine della stringa di input può essere un carattere di nuova riga finale\n
.L'elemento di linguaggio
.
corrisponde a qualsiasi carattere tranne\n
.Qualsiasi spazio vuoto in un criterio di ricerca di espressioni regolari viene interpretato come spazio letterale.
Nel confronto del criterio con la stringa di input vengono usate le convenzioni delle impostazioni cultura correnti.
I gruppi di acquisizione nel criterio di ricerca di espressioni regolari sono sia impliciti che espliciti.
Nota
L'opzione RegexOptions.None non ha un equivalente inline. Quando le opzioni di espressioni regolari vengono applicate inline, il comportamento predefinito viene ripristinato opzione per opzione, disattivando una particolare opzione. Ad esempio, (?i)
disattiva il confronto senza distinzione tra maiuscole e minuscole e (?-i)
lo ripristina.
Poiché l'opzione RegexOptions.Nonerappresenta il comportamento predefinito del motore delle espressioni regolari, raramente viene specificata in modo esplicito in una chiamata a metodo. Viene invece chiamato un costruttore o un metodo statico dei criteri di ricerca senza un parametro options
.
Corrispondenza senza distinzione tra maiuscole e minuscole
L'opzione IgnoreCase, o l'opzione inline i
, fornisce la corrispondenza senza distinzione tra maiuscole e minuscole. Per impostazione predefinita, vengono usate le convenzioni sulla combinazione di maiuscole e minuscole delle impostazioni cultura correnti.
L'esempio seguente definisce un criterio di ricerca di espressioni regolari, \bthe\w*\b
, che trova la corrispondenza di tutte le parole che iniziano con "the". Poiché la prima chiamata al metodo Match usa il confronto predefinito con distinzione tra maiuscole e minuscole, l'output indica che la stringa "The" che inizia la frase non viene individuata come corrispondenza. La corrispondenza viene individuata quando il metodo Match viene chiamato con le opzioni impostate su IgnoreCase.
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.
L'esempio seguente modifica il criterio di ricerca di espressioni regolari dell'esempio precedente in modo da usare opzioni inline anziché il parametro options
per fornire il confronto senza distinzione fra maiuscole e minuscole. Il primo criterio definisce l'opzione che non prevede la distinzione tra maiuscole e minuscole in un costrutto di raggruppamento che si applica solo alla lettera "t" nella stringa "the". Poiché il costrutto di opzione si trova all'inizio del criterio, il secondo criterio applica l'opzione che non prevede la distinzione tra maiuscole e minuscole all'intera espressione regolare.
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.
Modalità multiriga
L'opzione RegexOptions.Multiline, o l'opzione inline m
, consente al motore delle espressioni regolari di gestire una stringa di input composta da più righe. Modifica l'interpretazione degli elementi di linguaggio ^
e $
in modo che indichino l'inizio e la fine di una riga invece che l'inizio e la fine della stringa di input.
Per impostazione predefinita, $
verrà soddisfatta solo alla fine della stringa di input. Se si specifica l'opzione RegexOptions.Multiline, verrà soddisfatta dal carattere di nuova riga (\n
) o dalla fine della stringa di input.
In nessuno dei due casi $
riconosce la combinazione di caratteri di ritorno a capo/avanzamento riga (\r\n
). $
ignora sempre qualsiasi ritorno a capo (\r
). Per terminare la corrispondenza con \r\n
o \n
, usare la sottoespressione \r?$
anziché solo $
. Si noti che in questo modo il \r
sarà considerato come parte della corrispondenza.
L'esempio seguente estrae i nomi e i punteggi dei giocatori di bowling e li aggiunge a una raccolta SortedList<TKey,TValue> che li ordina in ordine decrescente. Il metodo Matches viene chiamato due volte. Nella prima chiamata al metodo, l'espressione regolare è ^(\w+)\s(\d+)$
e non sono impostate opzioni. Come mostra l'output, poiché il motore delle espressioni regolari non trova corrispondenza tra il criterio di input e l'inizio e la fine della stringa di input, non vengono individuate corrispondenze. Nella seconda chiamata al metodo, l'espressione regolare viene modificata in ^(\w+)\s(\d+)\r?$
e le opzioni sono impostate su RegexOptions.Multiline. Come mostra l'output, la corrispondenza tra i nomi e i punteggi viene individuata correttamente e i punteggi vengono visualizzati in ordine decrescente.
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
Il criterio di ricerca di espressioni regolari ^(\w+)\s(\d+)\r*$
è definito nel modo illustrato nella tabella seguente.
Modello | Descrizione |
---|---|
^ |
Comincia all'inizio della riga. |
(\w+) |
Trova la corrispondenza di uno o più caratteri alfanumerici. Equivale al primo gruppo di acquisizione. |
\s |
Trova la corrispondenza con uno spazio vuoto. |
(\d+) |
Trova la corrispondenza con una o più cifre decimali. Equivale al secondo gruppo di acquisizione. |
\r? |
Trova la corrispondenza di zero o un carattere di ritorno a capo. |
$ |
Termina alla fine della riga. |
L'esempio di seguito equivale al precedente, tranne il fatto che viene usata l'opzione inline (?m)
per impostare l'opzione multiriga.
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
Modalità a riga singola
L'opzione RegexOptions.Singleline, o l'opzione inline s
, consente al motore delle espressioni regolari di gestire la stringa di input come se fosse composta da una sola riga. Ciò avviene modificando il comportamento dell'elemento di linguaggio punto (.
) in modo che corrisponda a qualsiasi carattere anziché a qualsiasi carattere ad eccezione del carattere di nuova riga \n
.
L'esempio seguente illustra come cambia il comportamento dell'elemento di linguaggio .
quando si usa l'opzione RegexOptions.Singleline. L'espressione regolare ^.+
parte dall'inizio della stringa e individua una corrispondenza per ogni carattere. Per impostazione predefinita, la corrispondenza termina alla fine della prima riga. Il criterio di ricerca di espressioni regolari trova la corrispondenza del carattere di ritorno a capo, \r
, ma non di \n
. Poiché l'opzione RegexOptions.Singleline interpreta l'intera stringa di input come riga singola, ottiene una corrispondenza per ogni carattere nella stringa di input, incluso \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\.
L'esempio di seguito equivale al precedente, tranne il fatto che viene usata l'opzione inline (?s)
per impostare la modalità a riga singola.
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\.
Solo acquisizioni esplicite
Per impostazione predefinita, i gruppi di acquisizione vengono definiti dall'uso di parentesi nel criterio di ricerca di espressioni regolari. Ai gruppi denominati viene assegnato un nome o un numero dall'opzione di linguaggio (?<
nome>
sottoespressione)
, mentre i gruppi non denominati sono accessibili mediante indice. Nell'oggetto GroupCollection i gruppi non denominati precedono i gruppi denominati.
I costrutti di raggruppamento vengono spesso usati solo per applicare quantificatori a più elementi di linguaggio e le sottostringhe acquisite non sono di alcun interesse. Ad esempio, se l'espressione regolare seguente:
\b\(?((\w+),?\s?)+[\.!?]\)?
è intesa solo per l'estrazione di frasi che terminano con un punto, un punto esclamativo o un punto interrogativo da un documento, solo la frase risultante (rappresentata dall'oggetto Match) rappresenta un elemento di interesse. Le singola parole nella raccolta non lo sono.
I gruppi di acquisizione che successivamente non vengono usati possono risultare costosi, in quanto il motore delle espressioni regolari deve popolare entrambi gli oggetti raccolta GroupCollection e CaptureCollection. In alternativa, si può usare l'opzione RegexOptions.ExplicitCapture o l'opzione inline n
per specificare che le sole acquisizioni valide sono i gruppi denominati o numerati in modo esplicito definiti dal costrutto (?<
nome>
sottoespressione)
.
L'esempio seguente mostra informazioni sulle corrispondenze restituite dal criterio di ricerca di espressioni regolari \b\(?((\w+),?\s?)+[\.!?]\)?
quando viene chiamato il metodo Match con e senza l'opzione RegexOptions.ExplicitCapture. Come mostra l'output della prima chiamata al metodo, il motore delle espressioni regolari popola interamente gli oggetti raccolta GroupCollection e CaptureCollection con informazioni sulle sottostringhe acquisite. Poiché il secondo metodo viene chiamato con options
impostato su RegexOptions.ExplicitCapture, non acquisisce informazioni sui gruppi.
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.
Il criterio di ricerca di espressioni regolari \b\(?((?>\w+),?\s?)+[\.!?]\)?
è definito nel modo illustrato nella tabella seguente.
Modello | Descrizione |
---|---|
\b |
Inizia dal confine di una parola. |
\(? |
Trova la corrispondenza di una o nessuna parentesi di apertura ("("). |
(?>\w+),? |
Trova la corrispondenza di uno o più caratteri alfanumerici seguiti da una o nessuna virgola. Non eseguire il backtracking quando viene trovata la corrispondenza di caratteri alfanumerici. |
\s? |
Trova la corrispondenza di uno o nessuno spazio vuoto. |
((\w+),?\s?)+ |
Trova una o più volte la corrispondenza di una combinazione di uno o più caratteri alfanumerici, una o nessuna virgola e uno o nessuno spazio vuoto. |
[\.!?]\)? |
Trova la corrispondenza di qualsiasi dei tre simboli di punteggiatura, seguiti da una o nessuna parentesi di chiusura (")"). |
È anche possibile usare l'elemento inline (?n)
per disattivare le acquisizioni automatiche. L'esempio seguente modifica il criterio di ricerca di espressioni regolari precedente in modo da usare l'elemento inline (?n)
anziché l'opzione RegexOptions.ExplicitCapture.
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.
Infine, si può usare l'elemento di gruppo inline (?n:)
per disattivare le acquisizioni automatiche gruppo per gruppo. L'esempio di seguito modifica il criterio precedente per disattivare le acquisizioni non denominate nel gruppo esterno, ((?>\w+),?\s?)
. Notare che in questo modo vengono disattivare le acquisizioni non denominate anche nel gruppo interno.
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.
Espressioni regolari compilate
Nota
Dove possibile, usare le espressioni regolari generate dall'origine anziché compilare espressioni regolari usando l'opzioneRegexOptions.Compiled. La generazione di origine consente all'app di avviarsi in modo più rapido, di eseguire più velocemente e di essere più compatibile con il trimming. Per informazioni su quando è possibile generare l'origine, vedere Quando usarla.
Per impostazione predefinita, le espressioni regolari in .NET vengono interpretate. Quando viene creata un'istanza di un oggetto Regex o viene chiamato un metodo Regex statico, il criterio di ricerca di espressioni regolari viene convertito in un set di codici operativi personalizzati, che vengono usati da un interprete per eseguire l'espressione regolare. Questo comporta un compromesso: il tempo di inizializzazione del motore delle espressioni regolari viene ridotto al minimo, a scapito delle prestazioni in fase di esecuzione.
È possibile usare espressioni regolari compilate anziché interpretate mediante l'opzione RegexOptions.Compiled. In questo caso, quando un criterio viene passato al motore delle espressioni regolari, viene convertito in un set di codici operativi e quindi in linguaggio intermedio comune (CIL), che può essere passato direttamente a Common Language Runtime. Le espressioni regolari compilate massimizzano le prestazioni in fase di esecuzione a scapito del tempo di inizializzazione.
Nota
Un'espressione regolare può essere compilata solo fornendo il valore RegexOptions.Compiled al parametro options
di un costruttore di classe Regex o di un metodo statico dei criteri di ricerca. Non è disponibile come opzione inline.
È possibile usare le espressioni regolari compilate sia nelle chiamate a occorrenze statiche che nelle chiamate a istanze di espressioni regolari. Nelle espressioni regolari statiche, l'opzione RegexOptions.Compiled viene passata al parametro options
del metodo dei criteri di ricerca di espressioni regolari. Nelle istanze di espressioni regolari, viene passato al parametro options
del costruttore della classe Regex. In entrambi i casi, le prestazioni risultano migliorate.
Il miglioramento delle prestazioni, tuttavia, si verifica solo in presenza delle condizioni seguenti:
Un oggetto Regex che rappresenta una particolare espressione regolare viene usato in più chiamate a metodi dei criteri di ricerca di espressioni regolari.
L'oggetto Regex non può uscire dall'ambito, dunque può essere riutilizzato.
Un'espressione regolare statica viene usata in più chiamate a metodi dei criteri di ricerca di espressioni regolari. (Il miglioramento delle prestazioni è possibile perché le espressioni regolari usate nelle chiamate al metodo statico vengono memorizzate nella cache dal motore delle espressioni regolari.)
Nota
L'opzione RegexOptions.Compiled non è correlata al metodo obsoleto Regex.CompileToAssembly, che crea un assembly speciale che contiene espressioni regolari compilate predefinite.
Ignora spazi vuoti
Per impostazione predefinita, gli spazi vuoti in un criterio di ricerca di espressioni regolari sono significativi. Forzano il motore delle espressioni regolari a trovare una corrispondenza del carattere spazio nella stringa di input. Per questo motivo, l'espressione regolare "\b\w+\s
" e "\b\w+
" sono espressioni regolari pressoché equivalenti. Inoltre, quando il simbolo di cancelletto (#) viene incontrato in un criterio di ricerca di espressioni regolari, viene interpretato come carattere letterale di cui trovare la corrispondenza.
L'opzione RegexOptions.IgnorePatternWhitespace, o l'opzione inline x
, modifica questo comportamento predefinito come segue:
Gli spazi vuoti non di escape nel criterio di ricerca di espressioni regolari vengono ignorati. Per far parte di un criterio di ricerca di espressioni regolari, gli spazi vuoti devono essere preceduti da un carattere di escape (ad esempio
\s
o "\
").Il simbolo di cancelletto (#) viene interpretato come l'inizio di un commento anziché come un carattere letterale. Tutto il testo nel criterio di espressione regolare dal carattere
#
al carattere\n
successivo o alla fine della stringa viene interpretato come commento.
Nei casi seguenti, tuttavia, gli spazi in un'espressione regolare non vengono ignorati anche se si usa l'opzione RegexOptions.IgnorePatternWhitespace:
Uno spazio vuoto in una classe di caratteri viene sempre interpretato letteralmente. Ad esempio, il criterio di ricerca di espressioni regolari
[ .,;:]
trova la corrispondenza di qualsiasi spazio vuoto, punto, virgola, punto e virgola o due punti.Gli spazi vuoti non sono consentiti all'interno di un quantificatore tra parentesi, ad esempio
{
n}
,{
n,}
e{
n,
m}
. Ad esempio, il criterio di ricerca di espressioni regolari\d{1, 3}
non riesce a trovare sequenze di cifre da una a tre cifre perché contiene uno spazio vuoto.Gli spazi vuoti non sono consentiti all'interno di una sequenza di caratteri che introduce un elemento di linguaggio. Ad esempio:
L'elemento di linguaggio
(?:
sottoespressione)
rappresenta un gruppo di non acquisizione e la porzione(?:
dell'elemento non può contenere spazi vuoti. Il criterio(? :
sottoespressione)
genera un'eccezione ArgumentException in fase di esecuzione, perché il motore delle espressioni regolari non può analizzare il criterio e il criterio( ?:
sottoespressione)
non riesce a trovare la corrispondenza di sottoespressione.L'elemento di linguaggio
\p{
nome}
, che rappresenta una categoria Unicode o un blocco denominato, non può includere spazi vuoti nella porzione\p{
dell'elemento. Se si include uno spazio vuoto, l'elemento genera un'eccezione ArgumentException in fase di esecuzione.
Abilitare questa opzione consente di semplificare espressioni regolari spesso difficili da analizzare e capire. Migliora la leggibilità e rende possibile documentare un'espressione regolare.
L'esempio di seguito definisce il criterio di ricerca di espressioni regolari seguente:
\b \(? ( (?>\w+) ,?\s? )+ [\.!?] \)? # Matches an entire sentence.
Questo criterio è simile a quello definito nella sezione Solo acquisizioni esplicite, ad eccezione del fatto che usa l'opzione RegexOptions.IgnorePatternWhitespace per ignorare lo spazio vuoto del criterio.
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.
L'esempio seguente usa l'opzione inline (?x)
per ignorare lo spazio vuoto del criterio.
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.
Modalità da destra a sinistra
Per impostazione predefinita, il motore delle espressioni regolari effettua la ricerca da sinistra a destra. È possibile invertire la direzione della ricerca tramite l'opzione RegexOptions.RightToLeft. La ricerca da destra a sinistra inizia automaticamente nella posizione dell'ultimo carattere della stringa. Per i metodi dei criteri di ricerca che includono un parametro della posizione iniziale, ad esempio Regex.Match(String, Int32), la posizione iniziale specificata è l'indice della posizione dell'ultimo carattere a destra in corrispondenze del quale ha inizio la ricerca.
Nota
La modalità da destra a sinistra è disponibile solo fornendo il valore RegexOptions.RightToLeft al parametro options
di un costruttore della classe Regex o un metodo statico dei criteri di ricerca. Non è disponibile come opzione inline.
Esempio
L'espressione regolare \bb\w+\s
corrisponde a parole con due o più caratteri che iniziano con la lettera "b" e sono seguite da uno spazio vuoto. Nell'esempio seguente, la stringa di input è costituita da tre parole che comprendono uno o più caratteri "b". Le prime e le seconde parole iniziano con "b" e la terza parola termina con "b". Come illustrato nell'output dell'esempio di ricerca da destra a sinistra, solo le prime e le seconde parole corrispondono al criterio di espressione regolare, con la seconda parola corrispondente per prima.
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.
Ordine di valutazione
L'opzione RegexOptions.RightToLeft modifica la direzione di ricerca e inverte anche l'ordine in cui viene valutato il criterio di espressione regolare. In una ricerca da destra a sinistra, il criterio di ricerca viene letto da destra a sinistra. Questa distinzione è importante perché può influire su elementi come gruppi Capture e backreference. Ad esempio, l'espressione Regex.Match("abcabc", @"\1(abc)", RegexOptions.RightToLeft)
trova una corrispondenza abcabc
, ma in una ricerca da sinistra a destra (Regex.Match("abcabc", @"\1(abc)", RegexOptions.None)
), non viene trovata alcuna corrispondenza. Ciò avviene perché l'elemento deve essere valutato prima dell'elemento (abc)
gruppo di acquisizione numerato (\1
) per trovare una corrispondenza.
Le asserzioni lookahead e lookbehind
La posizione di una corrispondenza per un'asserzione lookahead ((?=subexpression)
) o lookbehind ((?<=subexpression)
) non cambia in una ricerca da destra a sinistra. Le asserzioni lookahead si riferiscono a una posizione a destra della posizione di corrispondenza corrente. Le asserzioni lookbehind si riferiscono a una posizione a sinistra della posizione di corrispondenza corrente.
Suggerimento
Indipendentemente dal fatto che una ricerca sia da destra a sinistra o meno, gli elemento lookbehind vengono implementati usando una ricerca da destra a sinistra a partire dalla posizione corrente della corrispondenza.
Ad esempio, l'espressione regolare (?<=\d{1,2}\s)\w+,\s\d{4}
usa l'asserzione lookbehind per testare una data che precede il nome di un mese. L'espressione regolare trova quindi la corrispondenza di mese e anno. Per informazioni sulle asserzioni lookahead e lookbehind, vedere Costrutti di raggruppamento.
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.
Il criterio di ricerca di espressioni regolari è definito nel modo illustrato nella tabella seguente.
Modello | Descrizione |
---|---|
(?<=\d{1,2}\s) |
L'inizio della corrispondenza deve essere preceduto da una o due cifre decimali seguite da uno spazio. |
\w+ |
Trova la corrispondenza di uno o più caratteri alfanumerici. |
, |
Trova la corrispondenza con un carattere virgola. |
\s |
Trova la corrispondenza con uno spazio vuoto. |
\d{4} |
Trova la corrispondenza con quattro cifre decimali. |
Comportamento di corrispondenza ECMAScript
Per impostazione predefinita, il motore delle espressioni regolari usa un comportamento canonico nella ricerca di corrispondenza di un criterio di ricerca di espressioni regolari nel testo di input. Si può però istruire il motore delle espressioni regolari in modo che usi il comportamento di corrispondenza ECMAScript specificando l'opzione RegexOptions.ECMAScript.
Nota
Il comportamento conforme a ECMAScript è disponibile solo fornendo il valore RegexOptions.ECMAScript al parametro options
di un costruttore della classe Regex o un metodo statico dei criteri di ricerca. Non è disponibile come opzione inline.
L'opzione RegexOptions.ECMAScript può essere combinata solo con le opzioni RegexOptions.IgnoreCase e RegexOptions.Multiline. L'uso di qualsiasi altra opzione in un'espressione regolare genera un'eccezione ArgumentOutOfRangeException.
Il comportamento di ECMAScript e quello delle espressioni regolari canoniche differiscono in tre aspetti: sintassi delle classi di caratteri, gruppi di acquisizione autoreferenziali e interpretazione degli ottali rispetto a quella dei backreference.
Sintassi delle classi di caratteri. Poiché le espressioni regolari canoniche supportano Unicode a differenza di ECMAScript, le classi di caratteri in ECMAScript hanno una sintassi più limitata e alcuni elementi di linguaggio delle classi di caratteri hanno un significato diverso. Ad esempio, ECMAScript non supporta elementi di linguaggio come la categoria Unicode o gli elementi di blocco
\p
e\P
. Analogamente, l'elemento\w
, che trova la corrispondenza di un carattere alfanumerico è equivalente alla classe di caratteri[a-zA-Z_0-9]
quando si usa ECMAScript e a[\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}\p{Lm}]
quando si usa il comportamento canonico. Per altre informazioni, vedere Classi di caratteri.L'esempio seguente illustra le differenze tra i criteri di ricerca canonici ed ECMAScript. Definisce un'espressione regolare,
\b(\w+\s*)+
, che trova la corrispondenza di parole seguite da spazi vuoti. L'input è costituito da due stringhe, una che usa il set di caratteri latini e l'altra che usa il set di caratteri cirillici. Come mostra l'output, la chiamata al metodo Regex.IsMatch(String, String, RegexOptions) che usa i criteri di ricerca ECMAScript non riesce a trovare la corrispondenza delle parole in cirillico, mentre la chiamata al metodo che usa i criteri di ricerca individua trova la corrispondenza.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.
Gruppi di acquisizione autoreferenziali. È necessario aggiornare una classe di acquisizione di espressioni regolari con un backreference autoreferenziale ogni volta che viene eseguita un'iterazione dell'acquisizione. Come mostra l'esempio seguente, questa funzionalità consente all'espressione regolare
((a+)(\1) ?)+
di trovare la corrispondenza della stringa di input " aa aaaa aaaaaa " quando si usa ECMAScript, ma non quando si usano i criteri di ricerca canonici.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 '
L'espressione regolare è definita nel modo illustrato nella tabella seguente.
Modello Descrizione (a+) Trova la corrispondenza della lettera "a" una o più volte. Equivale al secondo gruppo di acquisizione. (\1) Trova la corrispondenza della sottostringa acquisita dal primo gruppo di acquisizione. Equivale al terzo gruppo di acquisizione. ? Trova la corrispondenza di uno o nessuno spazio. ((a+)(\1) ?)+ Trova una o più volte la corrispondenza di uno o più caratteri "a" seguiti da una stringa che corrisponde al primo gruppo di acquisizione seguito da zero o da uno spazio vuoto. Equivale al primo gruppo di acquisizione. Risoluzione delle ambiguità tra caratteri di escape ottali e backreference. La tabella seguente contiene un riepilogo delle differenze tra l'interpretazione ottale e quella dei backreference nelle espressioni regolari canoniche e di ECMAScript.
Espressione regolare Comportamento canonico Comportamento ECMAScript \0
seguito da cifre ottali comprese tra 0 e 2Interpretare come un ottale. Ad esempio, \044
viene sempre interpretato come un valore ottale e significa "$".Stesso comportamento. \
seguito da una cifra compresa tra 1 e 9, quindi da nessuna cifra decimale aggiuntivaInterpretare come un backreference. Ad esempio, \9
rappresenta sempre un backreference 9, anche se il nono gruppo di acquisizione non esiste. Se il gruppo di acquisizione non esiste, il parser dell'espressione regolare genera un'eccezione ArgumentException.Se esiste un gruppo di acquisizione di una singola cifra decimale, il carattere viene considerato un backreference di tale cifra. Altrimenti il valore viene interpretato come un valore letterale. \
seguito da una cifra compresa tra 1 e 9, quindi da ulteriori cifre decimaliInterpretare le cifre come un valore decimale. Se tale gruppo di acquisizione esiste, l'espressione viene interpretata come un backreference.
In caso contrario, interpretare le cifre ottali iniziali fino all'ottale 377, ovvero considerare solo gli 8 bit inferiori del valore. Interpretare le cifre restanti come valori letterali. Ad esempio, nell'espressione\3000
, se il gruppo di acquisizione 300 esiste, l'espressione viene interpretata come un backreference 300; se il gruppo di acquisizione 300 non esiste, viene interpretata come ottale 300 seguito da 0.Interpretare come un backreference convertendo il maggior numero possibile di cifre a un valore decimale che si può riferire a un'acquisizione. Se non è possibile convertire alcuna cifra, interpretare il carattere come un ottale usando le cifre ottali iniziali fino all'ottale 377.
Confronto usando impostazioni di cultura inglese non dipendenti da paese/area geografica
Per impostazione predefinita, quando il motore delle espressioni regolari esegue confronti senza distinzione fra maiuscole e minuscole, usa le convenzioni sulla combinazione di maiuscole e minuscole delle impostazioni cultura correnti per determinare i caratteri maiuscoli e minuscoli equivalenti.
Tuttavia, questo comportamento risulta inappropriato per alcuni tipi di confronti, in particolare nel caso di confronto di input dell'utente con i nomi di risorse di sistema, ad esempio password, file o URL. Questo scenario è illustrato nell'esempio seguente. Il codice ha lo scopo di bloccare l'accesso a qualsiasi risorsa il cui URL è preceduto da FILE://. L'espressione regolare tenta una corrispondenza senza distinzione tra maiuscole e minuscole con la stringa tramite l'espressione regolare $FILE://
. Tuttavia, quando le impostazioni cultura del sistema correnti sono tr-TR (turco della Turchia), "I" non è l'equivalente maiuscolo di "i". Di conseguenza, la chiamata al metodo Regex.IsMatch restituisce false
e l'accesso al file è consentito.
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.
Nota
Per altre informazioni sui confronti di stringhe che supportano la distinzione tra maiuscole e minuscole e che usano la lingua inglese, vedere Procedure consigliate per l'uso di stringhe.
Invece di usare i confronti senza distinzione fra maiuscole e minuscole delle impostazioni cultura correnti, è possibile specificare l'opzione RegexOptions.CultureInvariant per ignorare le differenze culturali di lingua e usare le convenzioni della lingua inglese.
Nota
Il confronto usando la lingua inglese è disponibile solo fornendo il valore RegexOptions.CultureInvariant al parametro options
di un costruttore della classe Regex o un metodo statico dei criteri di ricerca. Non è disponibile come opzione inline.
L'esempio che segue è identico al precedente, tranne il fatto che il metodo statico Regex.IsMatch(String, String, RegexOptions) viene chiamato con opzioni che includono RegexOptions.CultureInvariant. Anche quando le impostazioni cultura correnti sono quelle del turco (Turchia), il motore delle espressioni regolari consente di individuare la corrispondenza tra "FILE" e "file" e di bloccare l'accesso alla risorsa del file.
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.
Modalità non backtracking
Per impostazione predefinita, il motore regex di .NET usa il backtracking per cercare le corrispondenze dei criteri. Un motore di backtracking è un motore che tenta di trovare una corrispondenza con un modello e, in caso di errore, torna indietro e tenta di trovare una corrispondenza con un criterio alternativo e così via. Un motore di backtracking è molto veloce per i casi tipici, ma rallenta man mano che aumenta il numero di alternanze di pattern, il che può portare a un backtracking irreversibile. L'opzione RegexOptions.NonBacktracking, introdotta in .NET 7, non usa il backtracking ed evita lo scenario peggiore. L'obiettivo è fornire un comportamento coerentemente valido, indipendentemente dall'input cercato.
L'opzione RegexOptions.NonBacktracking non supporta tutti gli altri motori predefiniti. In particolare, l'opzione non può essere usata insieme a RegexOptions.RightToLeft o RegexOptions.ECMAScript. Non consente inoltre i costrutti seguenti nel modello:
- Gruppi atomici
- Backreference
- Gruppo di bilanciamento
- Condizionali
- Lookaround
- Avviare ancoraggi (
\G
)
RegexOptions.NonBacktracking ha anche una sottile differenza per quanto riguarda l'esecuzione. Se un gruppo Capture si trova in un ciclo, la maggior parte dei motori regex (non .NET) fornisce solo l'ultimo valore corrispondente per tale acquisizione. Tuttavia, il motore regex di .NET tiene traccia di tutti i valori acquisiti all'interno di un ciclo e ne fornisce l'accesso. L'opzione RegexOptions.NonBacktracking è come la maggior parte delle altre implementazioni regex e supporta solo l'acquisizione finale.
Per altre informazioni sul backtracking, vedere Backtracking nelle espressioni regolari.