Opções de expressão regular
Por padrão, a comparação de uma cadeia de caracteres de entrada com quaisquer caracteres literais em um padrão de expressão regular diferencia maiúsculas de minúsculas, o espaço em branco em um padrão de expressão regular é interpretado como caracteres de espaço em branco literal e a captura de grupos em uma expressão regular é nomeada implícita e explicitamente. Você pode modificar esses e vários outros aspetos do comportamento de expressão regular padrão especificando opções de expressão regular. Algumas dessas opções, listadas na tabela a seguir, podem ser incluídas embutidas como parte do padrão de expressão regular ou podem ser fornecidas a um System.Text.RegularExpressions.Regex construtor de classe ou método de correspondência de padrão estático como um System.Text.RegularExpressions.RegexOptions valor de enumeração.
RegexOptions Membro |
Caractere embutido | Efeito | Mais informações |
---|---|---|---|
None | Não disponível | Use o comportamento padrão. | Opções padrão |
IgnoreCase | i |
Use a correspondência que não diferencia maiúsculas de minúsculas. | Correspondência que não diferencia maiúsculas de minúsculas |
Multiline | m |
Use o modo multilinha, onde ^ e $ indique o início e o fim de cada linha (em vez do início e do fim da cadeia de caracteres de entrada). |
Modo multilinha |
Singleline | s |
Use o modo de linha única, onde o ponto (.) corresponde a todos os caracteres (em vez de todos os caracteres, exceto \n ). |
Modo de linha única |
ExplicitCapture | n |
Não capture grupos sem nome. As únicas capturas válidas são grupos explicitamente nomeados ou numerados da subexpressão do nome > do formulário(?< .) |
Apenas capturas explícitas |
Compiled | Não disponível | Compile a expressão regular para um assembly. | Expressões regulares compiladas |
IgnorePatternWhitespace | x |
Exclua o espaço em branco sem escape do padrão e habilite comentários após um sinal numérico (# ). |
Ignorar espaço em branco |
RightToLeft | Não disponível | Altere a direção da pesquisa. A pesquisa move-se da direita para a esquerda em vez de da esquerda para a direita. | Modo da direita para a esquerda |
ECMAScript | Não disponível | Habilite o comportamento compatível com ECMAScript para a expressão. | Comportamento de correspondência ECMAScript |
CultureInvariant | Não disponível | Ignore as diferenças culturais na língua. | Comparação usando a cultura invariante |
NonBacktracking | Não disponível | Combine usando uma abordagem que evita backtracking e garante processamento em tempo linear no comprimento da entrada. (Disponível no .NET 7 e versões posteriores.) | Modo sem retrocesso |
Especificar opções
Você pode especificar opções para expressões regulares de uma das três maneiras:
options
No parâmetro de um System.Text.RegularExpressions.Regex construtor de classe ou estático (Shared
no Visual Basic) método de correspondência de padrões, como Regex(String, RegexOptions) ou Regex.Match(String, String, RegexOptions). Ooptions
parâmetro é uma combinação bit a bit OU de System.Text.RegularExpressions.RegexOptions valores enumerados.Quando as opções são fornecidas a uma Regex instância usando o
options
parâmetro de um construtor de classe, as opções são atribuídas à System.Text.RegularExpressions.RegexOptions propriedade. No entanto, a System.Text.RegularExpressions.RegexOptions propriedade não reflete opções embutidas no próprio padrão de expressão regular.O exemplo a seguir fornece uma ilustração. Ele usa o parâmetro do método para habilitar a correspondência sem diferenciação de maiúsculas
options
e minúsculas Regex.Match(String, String, RegexOptions) e ignorar o espaço em branco do padrão ao identificar palavras que começam com a letra "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.
Aplicando opções embutidas em um padrão de expressão regular com a sintaxe
(?imnsx-imnsx)
. A opção aplica-se ao padrão desde o ponto em que a opção é definida até o final do padrão ou até o ponto em que a opção é indefinida por outra opção embutida. Observe que a System.Text.RegularExpressions.RegexOptions propriedade de uma Regex instância não reflete essas opções embutidas. Para obter mais informações, consulte o tópico Construções diversas.O exemplo a seguir fornece uma ilustração. Ele usa opções embutidas para habilitar a correspondência sem diferenciação de maiúsculas e minúsculas e ignorar o espaço em branco do padrão ao identificar palavras que começam com a letra "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.
Aplicando opções embutidas em uma construção de agrupamento específica em um padrão de expressão regular com a subexpressão de sintaxe
(?imnsx-imnsx:
.)
Nenhum sinal antes de um conjunto de opções ligar o conjunto; um sinal de menos antes de um conjunto de opções desligar o conjunto.?
( é uma parte fixa da sintaxe da construção da linguagem que é necessária se as opções estiverem habilitadas ou desabilitadas.) A opção aplica-se apenas a esse grupo. Para obter mais informações, consulte Agrupando construções.O exemplo a seguir fornece uma ilustração. Ele usa opções embutidas em uma construção de agrupamento para habilitar a correspondência sem diferenciação de maiúsculas e minúsculas e ignorar o espaço em branco do padrão ao identificar palavras que começam com a letra "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 as opções forem especificadas em linha, um sinal de subtração (-
) antes de uma opção ou conjunto de opções desativará essas opções. Por exemplo, a construção (?ix-ms)
embutida ativa as RegexOptions.IgnoreCase opções e RegexOptions.IgnorePatternWhitespace desativa as opções e desativa as RegexOptions.Multiline opções e RegexOptions.Singleline . Todas as opções de expressão regular são desativadas por padrão.
Nota
Se as opções de expressão regular especificadas no parâmetro de um construtor ou chamada de método entrarem options
em conflito com as opções especificadas embutidas em um padrão de expressão regular, as opções embutidas serão usadas.
As cinco opções de expressão regular a seguir podem ser definidas com o parâmetro options e embutidas:
As cinco opções de expressão regular a seguir podem ser definidas usando o options
parâmetro, mas não podem ser definidas embutidas:
Determinar opções
Você pode determinar quais opções foram fornecidas a um Regex objeto quando ele foi instanciado recuperando o valor da propriedade somente Regex.Options leitura.
Para testar a presença de qualquer opção, exceto RegexOptions.None, execute uma operação AND com o valor do Regex.Options imóvel e o RegexOptions valor em que você está interessado. Em seguida, teste se o resultado é igual a esse RegexOptions valor. O exemplo a seguir testa se a RegexOptions.IgnoreCase opção foi definida.
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
Para testar RegexOptions.Noneo , determine se o valor da Regex.Options propriedade é igual a RegexOptions.None, como ilustra o exemplo a seguir.
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
As seções a seguir listam as opções suportadas pela expressão regular no .NET.
Opções padrão
A RegexOptions.None opção indica que nenhuma opção foi especificada e o mecanismo de expressão regular usa seu comportamento padrão. Tal inclui o seguinte:
O padrão é interpretado como uma expressão canônica em vez de uma expressão regular ECMAScript.
O padrão de expressão regular é correspondido na cadeia de caracteres de entrada da esquerda para a direita.
As comparações diferenciam maiúsculas de minúsculas.
Os
^
elementos e$
language indicam o início e o fim da cadeia de caracteres de entrada. O final da cadeia de caracteres de entrada pode ser um caractere de nova linha\n
à direita.O
.
elemento language corresponde a todos os caracteres, exceto\n
.Qualquer espaço em branco em um padrão de expressão regular é interpretado como um caractere de espaço literal.
As convenções da cultura atual são usadas ao comparar o padrão com a cadeia de caracteres de entrada.
A captura de grupos no padrão de expressão regular é implícita e explícita.
Nota
A RegexOptions.None opção não tem equivalente embutido. Quando as opções de expressão regular são aplicadas embutidas, o comportamento padrão é restaurado opção a opção, desativando uma opção específica. Por exemplo, (?i)
ativa a comparação que não diferencia maiúsculas de minúsculas e (?-i)
restaura a comparação padrão que diferencia maiúsculas de minúsculas.
Como a RegexOptions.None opção representa o comportamento padrão do mecanismo de expressão regular, raramente é especificada explicitamente em uma chamada de método. Um construtor ou método estático de correspondência de padrões sem um options
parâmetro é chamado em vez disso.
Correspondência que não diferencia maiúsculas de minúsculas
A IgnoreCase opção, ou a opção embutida, fornece correspondência que não diferencia maiúsculas i
de minúsculas. Por padrão, as convenções de invólucro da cultura atual são usadas.
O exemplo a seguir define um padrão de expressão regular, \bthe\w*\b
, que corresponde a todas as palavras começando com "the". Como a primeira chamada para o Match método usa a comparação padrão que diferencia maiúsculas de minúsculas, a saída indica que a cadeia de caracteres "The" que inicia a frase não é correspondida. Ele é correspondido quando o Match método é chamado com opções definidas como 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.
O exemplo a seguir modifica o padrão de expressão regular do exemplo anterior para usar opções embutidas em vez do options
parâmetro para fornecer comparação sem diferenciação de maiúsculas e minúsculas. O primeiro padrão define a opção que não diferencia maiúsculas de minúsculas em uma construção de agrupamento que se aplica apenas à letra "t" na cadeia de caracteres "the". Como a construção da opção ocorre no início do padrão, o segundo padrão aplica a opção que não diferencia maiúsculas de minúsculas a toda a expressão regular.
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.
Modo multilinha
A RegexOptions.Multiline opção, ou a m
opção embutida, permite que o mecanismo de expressão regular manipule uma cadeia de caracteres de entrada que consiste em várias linhas. Ele altera a ^
interpretação dos elementos e $
da linguagem para que eles indiquem o início e o fim de uma linha, em vez do início e do fim da cadeia de caracteres de entrada.
Por padrão, $
será satisfeito apenas no final da cadeia de caracteres de entrada. Se você especificar a RegexOptions.Multiline opção, ela será satisfeita pelo caractere de nova linha (\n
) ou pelo final da cadeia de caracteres de entrada.
Em nenhum dos casos reconhece $
a combinação de caracteres de retorno de carro/alimentação de linha (\r\n
). $
sempre ignora qualquer retorno de carro (\r
). Para terminar sua correspondência com um ou \r\n
\n
, use a subexpressão \r?$
em vez de apenas $
. Note que isso fará a \r
parte da partida.
O exemplo a seguir extrai nomes e pontuações de bowlers e os adiciona a uma SortedList<TKey,TValue> coleção que os classifica em ordem decrescente. O Matches método é chamado duas vezes. Na primeira chamada de método, a expressão regular é ^(\w+)\s(\d+)$
e nenhuma opção é definida. Como mostra a saída, como o mecanismo de expressão regular não pode corresponder ao padrão de entrada junto com o início e o fim da cadeia de caracteres de entrada, nenhuma correspondência é encontrada. Na segunda chamada de método, a expressão regular é alterada para ^(\w+)\s(\d+)\r?$
e as opções são definidas como RegexOptions.Multiline. Como mostra a saída, os nomes e pontuações são correspondidos com sucesso, e as pontuações são exibidas em ordem 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
O padrão ^(\w+)\s(\d+)\r*$
de expressão regular é definido conforme mostrado na tabela a seguir.
Padrão | Description |
---|---|
^ |
Comece no início da linha. |
(\w+) |
Corresponder a um ou mais caracteres de palavra. Este é o primeiro grupo de captura. |
\s |
Corresponder a um caractere de espaço em branco. |
(\d+) |
Corresponder a um ou mais dígitos decimais. Este é o segundo grupo de captura. |
\r? |
Corresponder a zero ou a um caractere de retorno de carro. |
$ |
Termine no final da linha. |
O exemplo a seguir é equivalente ao anterior, exceto que ele usa a opção (?m)
inline para definir a opção multilinha.
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
Modo de linha única
A RegexOptions.Singleline opção, ou a s
opção embutida, faz com que o mecanismo de expressão regular trate a cadeia de caracteres de entrada como se consistisse em uma única linha. Ele faz isso alterando o comportamento do elemento de linguagem de período (.
) para que ele corresponda a todos os caracteres, em vez de corresponder a todos os caracteres, exceto o caractere \n
de nova linha.
O exemplo a seguir ilustra como o comportamento do .
elemento language muda quando você usa a RegexOptions.Singleline opção. A expressão ^.+
regular começa no início da cadeia de caracteres e corresponde a todos os caracteres. Por padrão, a correspondência termina no final da primeira linha; O padrão de expressão regular corresponde ao caractere \r
de retorno de carro, mas não corresponde a \n
. Como a RegexOptions.Singleline opção interpreta toda a cadeia de caracteres de entrada como uma única linha, ela corresponde a todos os caracteres da cadeia de entrada, incluindo \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\.
O exemplo a seguir é equivalente ao anterior, exceto que ele usa a opção (?s)
embutida para habilitar o modo de linha única.
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\.
Apenas capturas explícitas
Por padrão, a captura de grupos é definida pelo uso de parênteses no padrão de expressão regular. Os grupos nomeados recebem um nome ou número pela opção de idioma de subexpressão de nome>
, enquanto os(?<
grupos sem nome são acessíveis por índice.)
GroupCollection No objeto, grupos sem nome precedem grupos nomeados.
Construções de agrupamento são frequentemente usadas apenas para aplicar quantificadores a vários elementos de linguagem, e as substrings capturadas não são de interesse. Por exemplo, se a seguinte expressão regular:
\b\(?((\w+),?\s?)+[\.!?]\)?
destina-se apenas a extrair frases que terminam com um ponto, ponto de exclamação ou ponto de interrogação de um documento, apenas a frase resultante (que é representada pelo Match objeto) é de interesse. As palavras individuais na coleção não são.
A captura de grupos que não são usados posteriormente pode ser cara, porque o mecanismo de expressão regular deve preencher os GroupCollection objetos e CaptureCollection a coleção. Como alternativa, você pode usar a RegexOptions.ExplicitCapture opção ou a n
opção embutida para especificar que as únicas capturas válidas são explicitamente nomeadas ou grupos numerados designados pela construção da (?<
subexpressão)
name>
.
O exemplo a seguir exibe informações sobre as correspondências retornadas pelo padrão de \b\(?((\w+),?\s?)+[\.!?]\)?
expressão regular quando o Match método é chamado com e sem a RegexOptions.ExplicitCapture opção. Como mostra a saída da primeira chamada de método, o mecanismo de expressão regular preenche totalmente os GroupCollection objetos e CaptureCollection coleção com informações sobre substrings capturadas. Como o segundo método é chamado com options
set to RegexOptions.ExplicitCapture, ele não captura informações sobre grupos.
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.
O padrão\b\(?((?>\w+),?\s?)+[\.!?]\)?
de expressão regular é definido conforme mostrado na tabela a seguir.
Padrão | Description |
---|---|
\b |
Comece por um limite de palavras. |
\(? |
Corresponder a zero ou uma ocorrência do parêntese de abertura ("("). |
(?>\w+),? |
Corresponder a um ou mais caracteres de palavras, seguidos de zero ou uma vírgula. Não volte atrás ao corresponder caracteres de palavras. |
\s? |
Corresponder a zero ou a um caractere de espaço em branco. |
((\w+),?\s?)+ |
Corresponder à combinação de um ou mais caracteres de palavra, zero ou uma vírgula e zero ou um caractere de espaço em branco uma ou mais vezes. |
[\.!?]\)? |
Corresponder a qualquer um dos três símbolos de pontuação, seguido de zero ou um parêntesis de fechamento (")"). |
Você também pode usar o (?n)
elemento embutido para suprimir capturas automáticas. O exemplo a seguir modifica o padrão de expressão regular anterior para usar o (?n)
elemento embutido em vez da RegexOptions.ExplicitCapture opção.
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.
Finalmente, você pode usar o elemento (?n:)
de grupo embutido para suprimir capturas automáticas grupo a grupo. O exemplo a seguir modifica o padrão anterior para suprimir capturas sem nome no grupo externo, ((?>\w+),?\s?)
. Observe que isso também suprime capturas sem nome no grupo 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.
Expressões regulares compiladas
Nota
Sempre que possível, use expressões regulares geradas pelo código-fonte em vez de compilar expressões regulares usando a RegexOptions.Compiled opção. A geração de código-fonte pode ajudar seu aplicativo a iniciar mais rápido, executar mais rapidamente e ser mais fácil de controlar. Para saber quando a geração de fontes é possível, consulte Quando usá-la.
Por padrão, expressões regulares no .NET são interpretadas. Quando um Regex objeto é instanciado ou um método estático Regex é chamado, o padrão de expressão regular é analisado em um conjunto de opcodes personalizados, e um intérprete usa esses opcodes para executar a expressão regular. Isso envolve uma compensação: o custo de inicialização do mecanismo de expressão regular é minimizado às custas do desempenho em tempo de execução.
Você pode usar expressões regulares compiladas em vez de interpretadas usando a RegexOptions.Compiled opção. Nesse caso, quando um padrão é passado para o mecanismo de expressão regular, ele é analisado em um conjunto de opcodes e, em seguida, convertido em Common Intermediate Language (CIL), que pode ser passado diretamente para o Common Language Runtime. Expressões regulares compiladas maximizam o desempenho em tempo de execução às custas do tempo de inicialização.
Nota
Uma expressão regular pode ser compilada somente fornecendo o RegexOptions.Compiled valor para o options
parâmetro de um Regex construtor de classe ou um método estático de correspondência de padrões. Não está disponível como uma opção em linha.
Você pode usar expressões regulares compiladas em chamadas para expressões estáticas e regulares de instância. Em expressões regulares estáticas, a RegexOptions.Compiled opção é passada para o options
parâmetro do método de correspondência de padrões de expressão regular. Em expressões regulares de instância, ele é passado para o options
Regex parâmetro do construtor de classe. Em ambos os casos, resulta num desempenho melhorado.
No entanto, esta melhoria no desempenho ocorre apenas nas seguintes condições:
Um Regex objeto que representa uma expressão regular específica é usado em várias chamadas para métodos de correspondência de padrões de expressão regular.
O Regex objeto não pode sair do escopo, por isso pode ser reutilizado.
Uma expressão regular estática é usada em várias chamadas para métodos de correspondência de padrões de expressão regular. (A melhoria de desempenho é possível porque as expressões regulares usadas em chamadas de método estático são armazenadas em cache pelo mecanismo de expressão regular.)
Nota
A RegexOptions.Compiled opção não está relacionada ao método obsoleto Regex.CompileToAssembly , que cria um assembly de finalidade especial que contém expressões regulares compiladas predefinidas.
Ignorar espaço em branco
Por padrão, o espaço em branco em um padrão de expressão regular é significativo; ele força o mecanismo de expressão regular a corresponder a um caractere de espaço em branco na cadeia de caracteres de entrada. Devido a isso, a expressão regular "\b\w+\s
" e "\b\w+
" são expressões regulares aproximadamente equivalentes. Além disso, quando o sinal numérico (#) é encontrado em um padrão de expressão regular, ele é interpretado como um caractere literal a ser correspondido.
A RegexOptions.IgnorePatternWhitespace opção, ou a x
opção embutida, altera esse comportamento padrão da seguinte maneira:
O espaço em branco sem escape no padrão de expressão regular é ignorado. Para fazer parte de um padrão de expressão regular, caracteres de espaço em branco devem ser escapados (por exemplo, como
\s
ou "\
").O sinal numérico (#) é interpretado como o início de um comentário, e não como um caractere literal. Todo o texto no padrão de expressão regular do caractere para o
#
próximo\n
caractere ou para o final da cadeia de caracteres, é interpretado como um comentário.
No entanto, nos seguintes casos, os caracteres de espaço em branco em uma expressão regular não são ignorados, mesmo se você usar a RegexOptions.IgnorePatternWhitespace opção:
O espaço em branco dentro de uma classe de caractere é sempre interpretado literalmente. Por exemplo, o padrão
[ .,;:]
de expressão regular corresponde a qualquer caractere de espaço em branco, ponto, vírgula, ponto-e-vírgula ou dois pontos.Espaço em branco não é permitido dentro de um quantificador entre colchetes, como
{
n}
,{
n,}
e{
n,
m.}
Por exemplo, o padrão\d{1, 3}
de expressão regular não corresponde a nenhuma sequência de dígitos de um a três dígitos porque contém um caractere de espaço em branco.O espaço em branco não é permitido em uma sequência de caracteres que introduz um elemento de idioma. Por exemplo:
A subexpressão do elemento
(?:
language representa um grupo que não captura e a(?:
parte do elemento não pode ter espaços incorporados.)
A subexpressão de padrão(? :
lança um ArgumentException em tempo de execução porque o mecanismo de expressão regular não pode analisar o padrão e a subexpressão)
de padrão( ?:
não corresponde à subexpressão.)
O nome
}
do elemento\p{
language, que representa uma categoria Unicode ou um bloco nomeado, não pode incluir espaços incorporados na\p{
parte do elemento. Se você incluir um espaço em branco, o elemento lançará um ArgumentException em tempo de execução.
Habilitar essa opção ajuda a simplificar expressões regulares que muitas vezes são difíceis de analisar e entender. Melhora a legibilidade e torna possível documentar uma expressão regular.
O exemplo a seguir define o seguinte padrão de expressão regular:
\b \(? ( (?>\w+) ,?\s? )+ [\.!?] \)? # Matches an entire sentence.
Esse padrão é semelhante ao padrão definido na seção Somente capturas explícitas, exceto que ele usa a opção para ignorar o RegexOptions.IgnorePatternWhitespace espaço em branco do padrão.
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.
O exemplo a seguir usa a opção (?x)
embutida para ignorar o espaço em branco padrão.
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.
Modo da direita para a esquerda
Por padrão, o mecanismo de expressão regular pesquisa da esquerda para a direita. Você pode inverter a direção da pesquisa usando a RegexOptions.RightToLeft opção. A pesquisa da direita para a esquerda começa automaticamente na última posição do caractere da cadeia de caracteres. Para métodos de correspondência de padrões que incluem um parâmetro de posição inicial, como Regex.Match(String, Int32), a posição inicial especificada é o índice da posição de caractere mais à direita na qual a pesquisa deve começar.
Nota
O modo de padrão da direita para a esquerda está disponível somente fornecendo o RegexOptions.RightToLeft valor para o options
parâmetro de um Regex construtor de classe ou método de correspondência de padrão estático. Não está disponível como uma opção em linha.
Exemplo
A expressão \bb\w+\s
regular corresponde a palavras com dois ou mais caracteres que começam com a letra "b" e são seguidas por um caractere de espaço em branco. No exemplo a seguir, a cadeia de caracteres de entrada consiste em três palavras que incluem um ou mais caracteres "b". A primeira e a segunda palavras começam com "b" e a terceira palavra termina com "b". Como mostra a saída do exemplo de pesquisa da direita para a esquerda, apenas a primeira e a segunda palavras correspondem ao padrão de expressão regular, com a segunda palavra sendo correspondida primeiro.
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.
Ordem de avaliação
A RegexOptions.RightToLeft opção altera a direção da pesquisa e também inverte a ordem na qual o padrão de expressão regular é avaliado. Numa pesquisa da direita para a esquerda, o padrão de pesquisa é lido da direita para a esquerda. Essa distinção é importante porque pode afetar coisas como grupos de captura e backreferences. Por exemplo, a expressão Regex.Match("abcabc", @"\1(abc)", RegexOptions.RightToLeft)
encontra uma correspondência abcabc
, mas em uma pesquisa da esquerda para a direita (Regex.Match("abcabc", @"\1(abc)", RegexOptions.None)
), nenhuma correspondência é encontrada. Isso porque o (abc)
elemento deve ser avaliado antes do elemento de grupo de captura numerado (\1
) para que uma correspondência seja encontrada.
Asserções "lookahead" e "lookbehind"
O local de uma correspondência para uma asserção lookahead ((?=subexpression)
) ou lookbehind ((?<=subexpression)
) não muda em uma pesquisa da direita para a esquerda. As asserções lookahead olham para a direita do local de partida atual; As asserções lookbehind olham para a esquerda do local atual da partida.
Gorjeta
Quer uma pesquisa seja da direita para a esquerda ou não, os lookbehinds são implementados usando uma pesquisa da direita para a esquerda a partir do local de correspondência atual.
Por exemplo, a expressão (?<=\d{1,2}\s)\w+,\s\d{4}
regular usa a asserção lookbehind para testar uma data que precede o nome de um mês. A expressão regular corresponde então ao mês e ao ano. Para obter informações sobre asserções lookahead e lookbehind, consulte Grouping Constructs.
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.
O padrão de expressão regular é definido conforme mostrado na tabela a seguir.
Padrão | Description |
---|---|
(?<=\d{1,2}\s) |
O início da correspondência deve ser precedido por um ou dois dígitos decimais seguidos de um espaço. |
\w+ |
Corresponder a um ou mais caracteres de palavra. |
, |
Corresponder a um caractere de vírgula. |
\s |
Corresponder a um caractere de espaço em branco. |
\d{4} |
Corresponder a quatro dígitos decimais. |
Comportamento de correspondência ECMAScript
Por padrão, o mecanismo de expressão regular usa um comportamento canônico ao fazer a correspondência de um padrão de expressão regular com o texto de entrada. No entanto, você pode instruir o mecanismo de expressão regular a usar o comportamento de correspondência ECMAScript especificando a RegexOptions.ECMAScript opção.
Nota
O comportamento compatível com ECMAScript está disponível somente fornecendo o RegexOptions.ECMAScript valor para o options
parâmetro de um Regex construtor de classe ou método de correspondência de padrão estático. Não está disponível como uma opção em linha.
A RegexOptions.ECMAScript opção só pode ser combinada com as RegexOptions.IgnoreCase opções e RegexOptions.Multiline . O uso de qualquer outra opção em uma expressão regular resulta em um ArgumentOutOfRangeExceptionarquivo .
O comportamento de ECMAScript e expressões regulares canônicas difere em três áreas: sintaxe de classe de caracteres, grupos de captura de autorreferência e interpretação octal versus backreference.
Sintaxe da classe de caracteres. Como expressões regulares canônicas suportam Unicode, enquanto ECMAScript não, as classes de caracteres em ECMAScript têm uma sintaxe mais limitada e alguns elementos de linguagem de classe de caracteres têm um significado diferente. Por exemplo, o ECMAScript não suporta elementos de linguagem como a categoria Unicode ou elementos
\p
de bloco e\P
. Da mesma forma, o\w
elemento , que corresponde a um caractere de palavra, é equivalente à classe de caractere ao usar ECMAScript[a-zA-Z_0-9]
e[\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}\p{Lm}]
ao usar comportamento canônico. Para obter mais informações, consulte Classes de caracteres.O exemplo a seguir ilustra a diferença entre a correspondência de padrões canônico e ECMAScript. Ele define uma expressão regular,
\b(\w+\s*)+
, que corresponde a palavras seguidas por caracteres de espaço em branco. A entrada consiste em duas cadeias de caracteres, uma que usa o conjunto de caracteres latinos e outra que usa o conjunto de caracteres cirílicos. Como mostra a saída, a chamada para o Regex.IsMatch(String, String, RegexOptions) método que usa a correspondência ECMAScript não corresponde às palavras cirílicas, enquanto a chamada de método que usa correspondência canônica corresponde a essas palavras.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.
Autorreferenciação de grupos de captura. Uma classe de captura de expressão regular com uma referência de retorno para si mesma deve ser atualizada a cada iteração de captura. Como mostra o exemplo a seguir, esse recurso permite que a expressão
((a+)(\1) ?)+
regular corresponda à cadeia de caracteres de entrada " aa aaaaaaa " ao usar ECMAScript, mas não ao usar correspondência canônica.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 '
A expressão regular é definida conforme mostrado na tabela a seguir.
Padrão Description (a+) Corresponda à letra "a" uma ou mais vezes. Este é o segundo grupo de captura. (\1) Corresponder à substring capturada pelo primeiro grupo de captura. Este é o terceiro grupo de captura. ? Corresponder a zero ou a um caractere de espaço. ((a+)(\1) ?) + Corresponder ao padrão de um ou mais caracteres "a" seguidos por uma cadeia de caracteres que corresponda ao primeiro grupo de captura seguido por zero ou um caractere de espaço uma ou mais vezes. Este é o primeiro grupo de captura. Resolução de ambiguidades entre fugas octais e retroreferências. A tabela a seguir resume as diferenças na interpretação octal versus backreference por expressões regulares canônicas e ECMAScript.
Regular expression Comportamento canônico Comportamento ECMAScript \0
seguido de 0 a 2 dígitos octaisInterprete como um octal. Por exemplo, \044
é sempre interpretado como um valor octal e significa "$".O mesmo comportamento. \
seguido de um algarismo de 1 a 9, seguido de nenhum algarismo decimal adicional,Interpretar como uma backreference. Por exemplo, \9
sempre significa backreference 9, mesmo que um nono grupo de captura não exista. Se o grupo de captura não existir, o analisador de expressão regular lançará um ArgumentExceptionarquivo .Se existir um único grupo de captura de dígitos decimais, faça referência a esse dígito. Caso contrário, interprete o valor como um literal. \
seguido de um algarismo de 1 a 9, seguido de algarismos decimais adicionaisInterprete os dígitos como um valor decimal. Se esse grupo de captura existir, interprete a expressão como uma backreference.
Caso contrário, interprete os dígitos octais principais até o octal 377; ou seja, considere apenas os 8 bits baixos do valor. Interprete os dígitos restantes como literais. Por exemplo, na expressão\3000
, se a captura do grupo 300 existir, interprete como backreference 300, se a captura do grupo 300 não existir, interprete como octal 300 seguido de 0.Interprete como uma referência de retorno convertendo o maior número possível de dígitos em um valor decimal que possa se referir a uma captura. Se nenhum dígito puder ser convertido, interprete como um octal usando os dígitos octais principais até o octal 377; interpretar os dígitos restantes como literais.
Compare usando a cultura invariante
Por padrão, quando o mecanismo de expressão regular executa comparações que não diferenciam maiúsculas de minúsculas, ele usa as convenções de invólucro da cultura atual para determinar caracteres equivalentes maiúsculos e minúsculos.
No entanto, esse comportamento é indesejável para alguns tipos de comparações, particularmente ao comparar a entrada do usuário com os nomes dos recursos do sistema, como senhas, arquivos ou URLs. O exemplo a seguir ilustra esse cenário. O código destina-se a bloquear o acesso a qualquer recurso cujo URL é precedido de FILE://. A expressão regular tenta uma correspondência que não diferencia maiúsculas de minúsculas com a cadeia de caracteres usando a expressão $FILE://
regular . No entanto, quando a cultura do sistema atual é tr-TR (turco-Türkiye), "I" não é o equivalente maiúsculo de "i". Como resultado, a chamada para o Regex.IsMatch método retorna false
e o acesso ao arquivo é permitido.
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
Para obter mais informações sobre comparações de cadeia de caracteres que diferenciam maiúsculas de minúsculas e que usam a cultura invariante, consulte Práticas recomendadas para o uso de cadeias de caracteres.
Em vez de usar as comparações sem diferenciação de maiúsculas e minúsculas da cultura atual, você pode especificar a RegexOptions.CultureInvariant opção para ignorar as diferenças culturais no idioma e usar as convenções da cultura invariante.
Nota
A comparação usando a cultura invariante só está disponível fornecendo o RegexOptions.CultureInvariant valor para o options
parâmetro de um Regex construtor de classe ou método de correspondência de padrões estáticos. Não está disponível como uma opção em linha.
O exemplo a seguir é idêntico ao exemplo anterior, exceto que o método estático Regex.IsMatch(String, String, RegexOptions) é chamado com opções que incluem RegexOptions.CultureInvariant. Mesmo quando a cultura atual é definida como turco (Türkiye), o mecanismo de expressão regular é capaz de corresponder com êxito "FILE" e "file" e bloquear o acesso ao recurso de arquivo.
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.
Modo sem retrocesso
Por padrão, . O mecanismo de regex da NET usa backtracking para tentar encontrar correspondências de padrões. Um mecanismo de backtracking é aquele que tenta corresponder a um padrão e, se isso falhar, volta atrás e tenta corresponder a um padrão alternativo, e assim por diante. Um mecanismo de backtracking é muito rápido para casos típicos, mas diminui à medida que o número de alterações de padrão aumenta, o que pode levar a retrocessos catastróficos. A RegexOptions.NonBacktracking opção, que foi introduzida no .NET 7, não usa backtracking e evita o pior cenário. Seu objetivo é proporcionar um bom comportamento consistente, independentemente da entrada que está sendo pesquisada.
A RegexOptions.NonBacktracking opção não suporta tudo o que os outros motores integrados suportam. Em particular, a opção não pode ser usada em conjunto com RegexOptions.RightToLeft ou RegexOptions.ECMAScript. Ele também não permite as seguintes construções no padrão:
- Grupos atómicos
- Referências posteriores
- Grupos de equilíbrio
- Condicionais
- Olhares
- Âncoras de arranque (
\G
)
RegexOptions.NonBacktracking também tem uma diferença sutil no que diz respeito à execução. Se um grupo de captura estiver em um loop, a maioria dos mecanismos regex (non-.NET) fornecerá apenas o último valor correspondente para essa captura. No entanto, . O mecanismo de regex da NET rastreia todos os valores que são capturados dentro de um loop e fornece acesso a eles. A RegexOptions.NonBacktracking opção é como a maioria das outras implementações de regex e só suporta fornecer a captura final.
Para obter mais informações sobre backtracking, consulte Backtracking em expressões regulares.