Share via


Detalhes do comportamento de expressões regulares

O mecanismo de expressões regulares do .NET Framework faz correspondências de referência passada de expressões regulares que incorpora um mecanismo Nondeterministic Finite Automaton (NFA) tradicional, como os usado em Perl, Python, Emacs e TCL. Isso o distingue de mecanismos mais rápidos, porém mais limitados, de pura expressão regular de Deterministic Finite Automaton (DFA), como os encontrados em awk, egrep ou lex. Isso também o distingue NFAs POSIX padronizados, porém mais lentos. A seção a seguir descreve os três tipos de mecanismos de expressão regular e explica por que regular expressões na.NET Framework são implementados usando um mecanismo de NFA tradicional.

Benefícios do mecanismo NFA

Quando os mecanismos DFA executam a correspondência de padrões, a sua ordem de processamento é controlado pela seqüência de entrada. O mecanismo começa no início da seqüência de entrada e prossegue seqüencialmente para determinar se o próximo caractere coincide com o padrão de expressão regular. Eles podem garantir coincidir com a seqüência mais longa possível. Porque eles nunca testar o mesmo caractere duas vezes, os mecanismos DFA não suportam backtracking. Entretanto, como um mecanismo de DFA contém apenas o estado finito, ele não pode corresponder a um padrão com referências anteriores e porque ele não constrói uma expansão explícita, ele não pode capturar subexpressões.

Ao contrário dos mecanismos de DFA quando mecanismos tradicionais de NFA executam a correspondência de padrões, sua ordem de processamento é impulsionado pelo padrão de expressão regular. Como ele processa um elemento de idioma específico, o mecanismo usa a correspondência greedy; Isto é, ela corresponde a seqüência de caracteres de entrada quanto como ela pode possivelmente. Mas ele também salva seu estado após a correspondência com êxito de uma subexpressão. Se uma correspondência eventualmente falhar, o mecanismo pode retornar a um estado salvo para que ele pode tentar correspondências adicionais. Esse processo de abandonando uma correspondência subexpressão bem-sucedidas para que os elementos de linguagem posteriores na expressão regular podem também fazer a correspondência é conhecido como backtracking. Os mecanismos NFA usam o backtracking para testar todas as expansões possíveis de uma expressão regular em uma ordem específica e aceitar a primeira correspondência. Porque um mecanismo de NFA tradicional constrói uma expansão específica da expressão regular para uma correspondência com êxito, ele pode capturar subexpressão correspondências e o correspondente de referências anteriores. No entanto, porque um NFA tradicional de volta, ele pode visitar o mesmo estado várias vezes se chegar no estado em caminhos diferentes. Como resultado, ele pode executar de forma exponencialmente mais lenta no caso mais grave. Porque um mecanismo de NFA tradicional aceita a primeira correspondem a ele localiza, também pode deixar a outras correspondências (possivelmente mais) não descobertas.

Mecanismos POSIX NFA são como mecanismos NFA tradicionais, exceto pelo fato de que eles continuam o retrocesso até que eles possam garantir que eles descobriram o correspondente mais longo possível. Como resultado, um mecanismo de NFA de POSIX é mais lento que um mecanismo de NFA tradicional e, quando você usa um mecanismo de NFA de POSIX, não podem favorecer uma correspondência mais curta por uma mais longa, alterando a ordem da pesquisa backtracking.

Mecanismos NFA tradicionais são favorecidos por programadores porque eles oferecem maior controle sobre a seqüência de caracteres de correspondência de mecanismos DFA ou de NFA de POSIX. Embora, na pior das hipóteses, eles podem executar lentamente, você pode orientá-los para encontrar correspondências em tempo polinomial ou linear usando padrões que reduzem a ambigüidades e limitam o backtracking. Em outras palavras, embora os mecanismos NFA negociar desempenho para poder e flexibilidade, na maioria dos casos, que eles oferecem boa para desempenho aceitável, se uma expressão regular bem-escrito e evita casos em que backtracking degrada o desempenho exponencialmente.

Observação

Para obter informações sobre a penalidade de desempenho causada por backtracking excessiva e de maneiras de criar uma expressão regular para trabalhar em torno deles, consulte Retrocedendo.

Recursos do Mecanismo .NET Framework

Para tirar proveito dos benefícios de um mecanismo de NFA tradicional, o.Mecanismo de expressão regular do NET Framework inclui um conjunto completo de construções para permitir que os programadores conduzir o mecanismo de backtracking. Esses construtores podem ser usados para localizar correspondências mais rápido ou favorecer expansões específicas sobre outras expansões.

Outros recursos do.Mecanismo de expressões regulares do NET Framework incluem o seguinte:

  • Quantificadores lentas: ??, *?, +?, {n,m}?. Essas construções informam o mecanismo de backtracking pesquise primeiro o número mínimo de repetições. Por outro lado, quantificadores comuns de ganância tentam coincidir com o número máximo de repetições pela primeira vez. O exemplo a seguir ilustra a diferença entre os dois. Uma expressão regular corresponde a uma frase que termina em um número e um grupo de captura destina-se extrair esse número. A expressão regular .+(\d+)\. inclui o quantificador greedy .+, que faz com que o mecanismo de expressões regulares capturar o último dígito do número. Em contraste, a expressão regular .+?(\d+)\. inclui o quantificador lazy .+?, que faz com que o mecanismo de expressões regulares capturar o número inteiro.

    Imports System.Text.RegularExpressions
    
    Module Example
       Public Sub Main()
          Dim greedyPattern As String = ".+(\d+)\."
          Dim lazyPattern As String = ".+?(\d+)\."
          Dim input As String = "This sentence ends with the number 107325."
          Dim match As Match
    
          ' Match using greedy quantifier .+.
          match = Regex.Match(input, greedyPattern)
          If match.Success Then
             Console.WriteLine("Number at end of sentence (greedy): {0}", 
                               match.Groups(1).Value)
          Else
             Console.WriteLine("{0} finds no match.", greedyPattern)
          End If
    
          ' Match using lazy quantifier .+?.
          match = Regex.Match(input, lazyPattern)
          If match.Success Then
             Console.WriteLine("Number at end of sentence (lazy): {0}", 
                               match.Groups(1).Value)
          Else
             Console.WriteLine("{0} finds no match.", lazyPattern)
          End If
       End Sub
    End Module
    ' The example displays the following output:
    '       Number at end of sentence (greedy): 5
    '       Number at end of sentence (lazy): 107325
    
    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
       public static void Main()
       {
          string greedyPattern = @".+(\d+)\.";
          string lazyPattern = @".+?(\d+)\.";
          string input = "This sentence ends with the number 107325.";
          Match match;
    
          // Match using greedy quantifier .+.
          match = Regex.Match(input, greedyPattern);
          if (match.Success)
             Console.WriteLine("Number at end of sentence (greedy): {0}", 
                               match.Groups[1].Value);
          else
             Console.WriteLine("{0} finds no match.", greedyPattern);
    
          // Match using lazy quantifier .+?.
          match = Regex.Match(input, lazyPattern);
          if (match.Success)
             Console.WriteLine("Number at end of sentence (lazy): {0}", 
                               match.Groups[1].Value);
          else
             Console.WriteLine("{0} finds no match.", lazyPattern);
       }
    }
    // The example displays the following output:
    //       Number at end of sentence (greedy): 5
    //       Number at end of sentence (lazy): 107325
    

    As versões greedy e lentas dessa expressão regular são definidas como mostrado na tabela a seguir.'

    Padrão

    Descrição

    .+(greedy quantificador)

    Corresponde a pelo menos uma ocorrência de qualquer caractere. Isso faz com que o mecanismo de expressões regulares coincidir com a seqüência inteira e, em seguida, para refazer o caminho como necessária para coincidir com o restante do padrão.

    .+?(quantificador lazy)

    Corresponde a pelo menos uma ocorrência de qualquer caractere, mas corresponde ao menor número possível.

    (\d+)

    Corresponder a pelo menos um caractere numérico e atribuí-lo ao primeiro grupo de captura.

    \.

    Corresponde a um período.

    Para obter mais informações sobre quantificadores preguiçosos, consulte Quantificadores.

  • Lookahead positivo: (?=subexpressão). Esse recurso permite que o mecanismo de backtracking retornar ao mesmo ponto no texto após a correspondência de uma subexpressão. É útil para pesquisa em todo o texto, verificando vários padrões que iniciam a partir da mesma posição. Ele também permite que o mecanismo verificar se existe uma subseqüência do final da correspondência sem incluir a subseqüência de caracteres no texto correspondente. O exemplo a seguir usa o lookahead positivo para extrair as palavras em uma frase que não forem seguidas por símbolos de pontuação.

    Imports System.Text.RegularExpressions
    
    Module Example
       Public Sub Main()
          Dim pattern As String = "\b[A-Z]+\b(?=\P{P})"
          Dim input As String = "If so, what comes next?"
          For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
             Console.WriteLine(match.Value)
          Next   
       End Sub
    End Module
    ' The example displays the following output:
    '       If
    '       what
    '       comes
    
    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
       public static void Main()
       {
          string pattern = @"\b[A-Z]+\b(?=\P{P})";
          string input = "If so, what comes next?";
          foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
             Console.WriteLine(match.Value);
       }
    }
    // The example displays the following output:
    //       If
    //       what
    //       comes
    

    A expressão regular \b[A-Z]+\b(?=\P{P}) é definido como mostrado na tabela a seguir.

    Padrão

    Descrição

    \b

    Começa a correspondência de um limite de palavra.

    [A-Z]+

    Corresponde a qualquer caractere alfabético uma ou mais vezes. Porque o Regex.Matches método é chamado com o RegexOptions.IgnoreCase opção, a comparação diferencia.

    \b

    Finalize a correspondência de um limite de palavra.

    (?=\P{P})

    Olhar à frente para determinar se o próximo caractere é um símbolo de pontuação. Se não for, a correspondência é bem-sucedida.

    Para obter mais informações sobre as declarações de lookahead positivo, consulte Agrupando Construtores.

  • Lookahead negativo: (?!subexpressão). Esse recurso adiciona a capacidade de corresponde somente se uma subexpressão falhar corresponder a uma expressão. Isso é particularmente poderoso para a remoção de uma pesquisa, porque geralmente é mais simples fornecer uma expressão para um caso em que deve ser eliminado de uma expressão para casos em que deve ser incluído. Por exemplo, é difícil escrever uma expressão para palavras que não começam com "não". O exemplo a seguir usa o lookahead negativo para excluí-los.

    Imports System.Text.RegularExpressions
    
    Module Example
       Public Sub Main()
          Dim pattern As String = "\b(?!non)\w+\b"
          Dim input As String = "Nonsense is not always non-functional."
          For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
             Console.WriteLine(match.Value)
          Next
       End Sub
    End Module
    ' The example displays the following output:
    '       is
    '       not
    '       always
    '       functional
    
    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
       public static void Main()
       {
          string pattern = @"\b(?!non)\w+\b";
          string input = "Nonsense is not always non-functional.";
          foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
             Console.WriteLine(match.Value);
       }
    }
    // The example displays the following output:
    //       is
    //       not
    //       always
    //       functional
    

    O padrão de expressão regular \b(?!non)\w+\b é definido como mostrado na tabela a seguir.

    Padrão

    Descrição

    \b

    Começa a correspondência de um limite de palavra.

    (?! non)

    Olhar à frente garantir que a seqüência de caracteres atual não começa com "não". Em caso afirmativo, a correspondência falha.

    (\w+)

    Corresponde a um ou mais caracteres do word.

    \b

    Finalize a correspondência de um limite de palavra.

    Para obter mais informações sobre as declarações de lookahead negativo, consulte Agrupando Construtores.

  • Avaliação condicional: (?(expressão)Sim|não) e (?(nome)Sim|não), onde expressão é uma subexpressão para corresponder, nome é o nome de um grupo de captura, Sim é a seqüência de caracteres para corresponder ao se expressão é correspondido ou nome é um grupo capturado válido, não vazio, e sem é a subexpressão para corresponder ao se expressão não corresponde ou nome não é um grupo capturado válido, não vazio. Esse recurso permite que o mecanismo de pesquisa usando mais de um padrão alternativo, dependendo do resultado de uma correspondência de subexpressão anterior ou o resultado de uma declaração de largura zero. Isso permite uma forma mais eficiente de retrorreferência permite, por exemplo, a correspondência de uma subexpressão com base em se coincidiu uma subexpressão anterior. A expressão regular no exemplo a seguir corresponde a parágrafos são destinados a uso interno e público. Parágrafos destinados apenas para uso interno começam com um <PRIVATE> marca. O padrão de expressão regular ^(?<Pvt>\<PRIVATE\>\s)?(?(Pvt)((\w+\p{P}?\s)+)|((\w+\p{P}?\s)+))\r?$ usa a avaliação condicional para atribuir o conteúdo dos parágrafos destinados para o público e para uso interno separar grupos de captura. Estes parágrafos, em seguida, podem ser tratados de forma diferente.

    Imports System.Text.RegularExpressions
    
    Module Example
       Public Sub Main()
          Dim input As String = "<PRIVATE> This is not for public consumption." + vbCrLf + _
                                "But this is for public consumption." + vbCrLf + _
                                "<PRIVATE> Again, this is confidential." + vbCrLf
          Dim pattern As String = "^(?<Pvt>\<PRIVATE\>\s)?(?(Pvt)((\w+\p{P}?\s)+)|((\w+\p{P}?\s)+))\r?$"
          Dim publicDocument As String = Nothing
          Dim privateDocument As String = Nothing
    
          For Each match As Match In Regex.Matches(input, pattern, RegexOptions.Multiline)
             If match.Groups(1).Success Then
                privateDocument += match.Groups(1).Value + vbCrLf
             Else
                publicDocument += match.Groups(3).Value + vbCrLf   
                privateDocument += match.Groups(3).Value + vbCrLf
             End If  
          Next
    
          Console.WriteLine("Private Document:")
          Console.WriteLine(privateDocument)
          Console.WriteLine("Public Document:")
          Console.WriteLine(publicDocument)
       End Sub
    End Module
    ' The example displays the following output:
    '    Private Document:
    '    This is not for public consumption.
    '    But this is for public consumption.
    '    Again, this is confidential.
    '    
    '    Public Document:
    '    But this is for public consumption.
    
    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
       public static void Main()
       {
          string input = "<PRIVATE> This is not for public consumption." + Environment.NewLine + 
                         "But this is for public consumption." + Environment.NewLine + 
                         "<PRIVATE> Again, this is confidential.\n";  
          string pattern = @"^(?<Pvt>\<PRIVATE\>\s)?(?(Pvt)((\w+\p{P}?\s)+)|((\w+\p{P}?\s)+))\r?$";
          string publicDocument = null, privateDocument = null;
    
          foreach (Match match in Regex.Matches(input, pattern, RegexOptions.Multiline))
          {
             if (match.Groups[1].Success) {
                privateDocument += match.Groups[1].Value + "\n";
             }
             else {
                publicDocument += match.Groups[3].Value + "\n";   
                privateDocument += match.Groups[3].Value + "\n";
             }  
          }
    
          Console.WriteLine("Private Document:");
          Console.WriteLine(privateDocument);
          Console.WriteLine("Public Document:");
          Console.WriteLine(publicDocument);
       }
    }
    // The example displays the following output:
    //    Private Document:
    //    This is not for public consumption.
    //    But this is for public consumption.
    //    Again, this is confidential.
    //    
    //    Public Document:
    //    But this is for public consumption.
    

    O padrão de expressão regular é definido como mostrado na tabela a seguir.

    Padrão

    Descrição

    ^

    Começa a correspondência no início de uma linha.

    (?<Pvt>\<PRIVATE\>\s)?

    Corresponde a zero ou uma de ocorrência da seqüência <PRIVATE> seguido por um caractere de espaço em branco. Atribuir a correspondência para um grupo de captura chamado Pvt.

    (?(Pvt)((\w+\p{P}? \s)+)

    Se o Pvt captura o grupo existe, corresponde a uma ou mais ocorrências de um ou mais caracteres alfabéticos, seguidos de zero ou o separador de uma pontuação, seguido por um caractere de espaço em branco. Atribua a subseqüência do primeiro grupo de captura.

    |((\w+\p{P}? \s)+))

    Se a Pvt a captura de grupo não existe, corresponder a um ou mais ocorrências de um ou mais caracteres de palavra seguido de zero ou um separador de pontuação, seguido por um caractere de espaço em branco. Atribua a subseqüência de caracteres para o terceiro grupo de capturando.

    \r?$

    Corresponde ao final de uma linha ou final da seqüência de caracteres.

    Para obter mais informações sobre a avaliação condicional, consulte Construtores de Alternância.

  • Balanceamento de definições de grupo: (?<Nome1-nome2> subexpressão). Esse recurso permite que o mecanismo de expressões regulares controlar aninhadas construções como, por exemplo, parênteses ou a abertura e fechamento de parênteses. Para um exemplo, consulte Agrupando Construtores.

  • Subexpressões de nonbacktracking (também conhecido como greedy subexpressões): (?>subexpressão). Esse recurso permite que o mecanismo de backtracking garantir que uma subexpressão corresponde apenas a primeira correspondência encontrada para esse subexpressão, como se a expressão estava em execução independente de sua expressão contendo. Se você não usar essa construção, pesquisas backtracking da expressão maior podem alterar o comportamento de uma subexpressão. Por exemplo, a expressão regular (a+)\w corresponde a um ou mais "a" caracteres, juntamente com um caractere de palavra que segue a seqüência de "a" caracteres e atribui a seqüência de "a" caracteres para o primeiro grupo de capturando, no entanto, se o caractere de final de seqüência de entrada também é um "a" it corresponde a \w elemento de linguagem e não está incluído no grupo capturados.

    Imports System.Text.RegularExpressions
    
    Module Example
       Public Sub Main()
          Dim inputs() As String = { "aaaaa", "aaaaab" }
          Dim backtrackingPattern As String = "(a+)\w"
          Dim match As Match
    
          For Each input As String In inputs
             Console.WriteLine("Input: {0}", input)
             match = Regex.Match(input, backtrackingPattern)
             Console.WriteLine("   Pattern: {0}", backtrackingPattern)
             If match.Success Then 
                Console.WriteLine("      Match: {0}", match.Value)
                Console.WriteLine("      Group 1: {0}", match.Groups(1).Value)
             Else 
                Console.WriteLine("      Match failed.")
             End If   
          Next
          Console.WriteLine()            
       End Sub
    End Module
    ' The example displays the following output:
    '       Input: aaaaa
    '          Pattern: (a+)\w
    '             Match: aaaaa
    '             Group 1: aaaa
    '       Input: aaaaab
    '          Pattern: (a+)\w
    '             Match: aaaaab
    '             Group 1: aaaaa
    
    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
       public static void Main()
       {
          string[] inputs = { "aaaaa", "aaaaab" };
          string backtrackingPattern = @"(a+)\w";
          Match match;
    
          foreach (string input in inputs) {
             Console.WriteLine("Input: {0}", input);
             match = Regex.Match(input, backtrackingPattern);
             Console.WriteLine("   Pattern: {0}", backtrackingPattern);
             if (match.Success) { 
                Console.WriteLine("      Match: {0}", match.Value);
                Console.WriteLine("      Group 1: {0}", match.Groups[1].Value);
             }
             else {
                Console.WriteLine("      Match failed.");
             }   
          }
          Console.WriteLine();            
       }
    }
    // The example displays the following output:
    //       Input: aaaaa
    //          Pattern: (a+)\w
    //             Match: aaaaa
    //             Group 1: aaaa
    //       Input: aaaaab
    //          Pattern: (a+)\w
    //             Match: aaaaab
    //             Group 1: aaaaa
    

    A expressão regular ((?>a+))\w impede que esse comportamento. Porque todos consecutivos "a" caracteres têm correspondência sem backtracking, o primeiro grupo de capturando inclui tudo consecutivas "a" caracteres. Se a "a" caracteres não forem seguidos pelo menos um caractere diferente de "a", a correspondência falha.

    Imports System.Text.RegularExpressions
    
    Module Example
       Public Sub Main()
          Dim inputs() As String = { "aaaaa", "aaaaab" }
          Dim nonbacktrackingPattern As String = "((?>a+))\w"
          Dim match As Match
    
          For Each input As String In inputs
             Console.WriteLine("Input: {0}", input)
             match = Regex.Match(input, nonbacktrackingPattern)
             Console.WriteLine("   Pattern: {0}", nonbacktrackingPattern)
             If match.Success Then 
                Console.WriteLine("      Match: {0}", match.Value)
                Console.WriteLine("      Group 1: {0}", match.Groups(1).Value)
             Else 
                Console.WriteLine("      Match failed.")
             End If   
          Next
          Console.WriteLine()            
       End Sub
    End Module
    ' The example displays the following output:
    '       Input: aaaaa
    '          Pattern: ((?>a+))\w
    '             Match failed.
    '       Input: aaaaab
    '          Pattern: ((?>a+))\w
    '             Match: aaaaab
    '             Group 1: aaaaa
    
    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
       public static void Main()
       {
          string[] inputs = { "aaaaa", "aaaaab" };
          string nonbacktrackingPattern = @"((?>a+))\w";
          Match match;
    
          foreach (string input in inputs) {
             Console.WriteLine("Input: {0}", input);
             match = Regex.Match(input, nonbacktrackingPattern);
             Console.WriteLine("   Pattern: {0}", nonbacktrackingPattern);
             if (match.Success) { 
                Console.WriteLine("      Match: {0}", match.Value);
                Console.WriteLine("      Group 1: {0}", match.Groups[1].Value);
             }
             else {
                Console.WriteLine("      Match failed.");
             }   
          }
          Console.WriteLine();            
       }
    }
    // The example displays the following output:
    //       Input: aaaaa
    //          Pattern: ((?>a+))\w
    //             Match failed.
    //       Input: aaaaab
    //          Pattern: ((?>a+))\w
    //             Match: aaaaab
    //             Group 1: aaaaa
    

    Para obter mais informações sobre subexpressões nonbacktracking, consulte Agrupando Construtores.

  • Direita para a esquerda correspondentes, que é especificada, fornecendo a RegexOptions.RightToLeft opção para um Regex Construtor de classe ou instância estática o método correspondente. Esse recurso é útil quando a pesquisa da direita para a esquerda em vez da esquerda para direita ou em casos onde é mais eficiente para começar uma correspondência na parte direita do padrão em vez da esquerda. Como o exemplo a seguir ilustra, usando a correspondência da direita para esquerda pode alterar o comportamento de quantificadores greedy. O exemplo realiza duas pesquisas de uma frase que termina em um número. A pesquisa da esquerda para direita que usa o quantificador greedy + corresponde a um dos seis dígitos na frase, enquanto a pesquisa da direita para esquerda corresponde a todos os seis dígitos. Para obter uma descrição padrão da expressão regular, consulte o exemplo que ilustra quantificadores preguiçosos anteriormente nesta seção.

    Imports System.Text.RegularExpressions
    
    Module Example
       Public Sub Main()
          Dim greedyPattern As String = ".+(\d+)\."
          Dim input As String = "This sentence ends with the number 107325."
          Dim match As Match
    
          ' Match from left-to-right using lazy quantifier .+?.
          match = Regex.Match(input, greedyPattern)
          If match.Success Then
             Console.WriteLine("Number at end of sentence (left-to-right): {0}", 
                               match.Groups(1).Value)
          Else
             Console.WriteLine("{0} finds no match.", greedyPattern)
          End If
    
          ' Match from right-to-left using greedy quantifier .+.
          match = Regex.Match(input, greedyPattern, RegexOptions.RightToLeft)
          If match.Success Then
             Console.WriteLine("Number at end of sentence (right-to-left): {0}", 
                               match.Groups(1).Value)
          Else
             Console.WriteLine("{0} finds no match.", greedyPattern)
          End If
       End Sub
    End Module
    ' The example displays the following output:
    '       Number at end of sentence (left-to-right): 5
    '       Number at end of sentence (right-to-left): 107325
    
    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
       public static void Main()
       {
          string greedyPattern = @".+(\d+)\.";
          string input = "This sentence ends with the number 107325.";
          Match match;
    
          // Match from left-to-right using lazy quantifier .+?.
          match = Regex.Match(input, greedyPattern);
          if (match.Success)
             Console.WriteLine("Number at end of sentence (left-to-right): {0}", 
                               match.Groups[1].Value);
          else
             Console.WriteLine("{0} finds no match.", greedyPattern);
    
          // Match from right-to-left using greedy quantifier .+.
          match = Regex.Match(input, greedyPattern, RegexOptions.RightToLeft);
          if (match.Success)
             Console.WriteLine("Number at end of sentence (right-to-left): {0}", 
                               match.Groups[1].Value);
          else
             Console.WriteLine("{0} finds no match.", greedyPattern);
       }
    }
    // The example displays the following output:
    //       Number at end of sentence (left-to-right): 5
    //       Number at end of sentence (right-to-left): 107325
    

    Para obter mais informações sobre a correspondência da direita para esquerda, consulte Opções de expressões regulares.

  • Lookbehind de positivo e negativo: (?<=subexpressão) para lookbehind positivo, e (?<!subexpressão) para lookbehind negativo. Esse recurso é semelhante ao lookahead, que é discutido anteriormente neste tópico. Devido ao mecanismo de expressões regulares permitir correspondência completa da direita para esquerda, expressões regulares permitem irrestrios lookbehinds. Lookbehind positivo e negativo também pode ser usado para evitar o aninhamento de quantificadores quando a subexpressão aninhada é um superconjunto de uma expressão externa. Expressões regulares com tais quantificadores aninhados geralmente oferecem um desempenho ruim. Por exemplo, o exemplo a seguir verifica se uma seqüência de caracteres começa e termina com um caractere alfanumérico, e que qualquer outro caractere na seqüência de caracteres é um de um subconjunto de maior. Ele forma uma parte da expressão regular usada para validar os endereços de email; Para obter mais informações, consulte Como: Verifique se as seqüências estão em formato de email válido.

    Imports System.Text.RegularExpressions
    
    Module Example
       Public Sub Main()
          Dim inputs() As String = { "jack.sprat", "dog#", "dog#1", "me.myself", 
                                     "me.myself!" }
          Dim pattern As String = "^[A-Z0-9]([-!#$%&'.*+/=?^`{}|~\w])*(?<=[A-Z0-9])$"
          For Each input As String In inputs
             If Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase) Then
                Console.WriteLine("{0}: Valid", input)
             Else
                Console.WriteLine("{0}: Invalid", input)
             End If   
          Next
       End Sub
    End Module
    ' The example displays the following output:
    '       jack.sprat: Valid
    '       dog#: Invalid
    '       dog#1: Valid
    '       me.myself: Valid
    '       me.myself!: Invalid
    
    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
       public static void Main()
       {
          string[] inputs = { "jack.sprat", "dog#", "dog#1", "me.myself", 
                              "me.myself!" };
          string pattern = @"^[A-Z0-9]([-!#$%&'.*+/=?^`{}|~\w])*(?<=[A-Z0-9])$";
          foreach (string input in inputs) {
             if (Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase))
                Console.WriteLine("{0}: Valid", input);
             else
                Console.WriteLine("{0}: Invalid", input);
          }
       }
    }
    // The example displays the following output:
    //       jack.sprat: Valid
    //       dog#: Invalid
    //       dog#1: Valid
    //       me.myself: Valid
    //       me.myself!: Invalid
    

    A expressão regular ^[A-Z0-9]([-!#$%&'.*+/=?^`{}|~\w])*(?<=[A-Z0-9])$ é definido como mostrado na tabela a seguir.

    Padrão

    Descrição

    ^

    Começa a correspondência no início da seqüência de caracteres.

    [A-Z0-9]

    Corresponde a qualquer caractere numérico ou alfanumérico. (A comparação é diferencia maiúsculas de minúsculas).

    ([-!#$%&'.*+/=?^`{}|~\w])*

    Corresponde a zero ou mais ocorrências de qualquer caractere de palavra ou de qualquer um dos seguintes caracteres: -, !, #, $, %, &, ', ., *, +, /, =, ?, ^, `, {, }, |, or ~.

    (?<=[A-Z0-9])

    Procure por trás para o caractere anterior, o que deve ser numéricos ou alfanuméricos. (A comparação é diferencia maiúsculas de minúsculas).

    $

    Finalize a correspondência ao final da seqüência de caracteres.

    Para obter mais informações sobre o lookbehind positivo e negativo, consulte Agrupando Construtores.

Tópicos relacionados

Título

Descrição

Retrocedendo

Fornece informações sobre como expressão regular Retrocedendo se ramifica para localizar correspondências alternativas.

Compilação e Reuso

Fornece informações sobre a compilação e a reutilização de expressões regulares para aumentar o desempenho.

Acesso thread-safe

Fornece informações sobre segurança do thread de expressão regular e explica quando você deve sincronizar o acesso a objetos de expressão regular.

Expressões Regulares do .NET Framework

Fornece uma visão geral sobre o aspecto de linguagem de programação das expressões regulares.

O modelo de objeto de expressão Regular

Fornece informações e exemplos de código que ilustram como usar as classes de expressões regulares.

Exemplos de Expressões Regulares

Contém exemplos de códigos que ilustram o uso de expressões regulares em aplicativos comuns.

Elementos de linguagem das expressões regulares

Fornece informações sobre o conjunto de caracteres, operadores e construções que você pode usar para definir expressões regulares.

Referência

System.Text.RegularExpressions