Tutorial de Introdução ao Regex em 30 Minutos

Tutorial de Introdução ao Regex em 30 Minutos

Objetivo do artigo

Entender o que é uma expressão regular em 30 minutos e ter uma compreensão básica para que você possa usá-la em seus programas ou páginas da web.

Como usar este tutorial

Não se deixe intimidar pelas expressões complexas abaixo; basta seguir meu passo a passo e você descobrirá que as expressões regulares não são tão difíceis quanto você imagina. Claro, se depois de ler este tutorial você perceber que entendeu muito, mas quase não se lembra de nada, isso é normal - eu acredito que a probabilidade de alguém que nunca teve contato com expressões regulares lembrar mais de 80% da sintaxe mencionada após ler este tutorial é praticamente zero. Aqui, o objetivo é apenas fazer você entender os princípios básicos; no futuro, você precisará praticar mais e usar frequentemente para dominar as expressões regulares.

O mais importante é - por favor, me dê. 30 minutos Se você não tem experiência com expressões regulares, não tente em 30. segundo Porta interna - a menos que você seja o Superman :)

Além de servir como um tutorial introdutório, este artigo também tenta ser um manual de referência de sintaxe de expressões regulares que pode ser usado no dia a dia. Com base na experiência do autor, esse objetivo foi alcançado de forma satisfatória — veja, eu mesmo não consegui lembrar de tudo, não é?

Limpar formatação Convenções de formato de texto: termos técnicos Metacaracteres/formato de sintaxe expressão regular Uma parte da expressão regular (usada para análise) String de origem para correspondência. Explicação sobre expressões regulares ou uma de suas partes.

Notas de rodapé ocultas À direita deste texto, há algumas notas que servem principalmente para fornecer informações relevantes ou explicar conceitos básicos para leitores sem formação em programação, e geralmente podem ser ignoradas.

O que é exatamente uma expressão regular?

Ao desenvolver programas ou páginas da web que manipulam strings, frequentemente é necessário buscar strings que atendam a certas regras complexas. expressão regular É uma ferramenta utilizada para descrever essas regras. Em outras palavras, expressões regulares são códigos que registram regras de texto.

É muito provável que você tenha usado o comando de busca de arquivos no Windows/Dos. curinga wildcard ) ou seja * e ? Se você quiser encontrar todos os documentos do Word em um diretório específico, você deve procurar. * .doc Aqui, * pode ser interpretado como qualquer string. Semelhante aos caracteres curinga, as expressões regulares também são uma ferramenta para correspondência de texto, mas, em comparação com os caracteres curinga, elas podem descrever suas necessidades de forma mais precisa - é claro, o custo é que são mais complexas - por exemplo, você pode escrever uma expressão regular para encontrar Todas as strings que começam com 0, seguidas por 2 a 3 dígitos, depois um hífen "-" e, por fim, 7 ou 8 dígitos. (como) 010-12345678 ou 0376-7654321 )。

caractere É a unidade mais básica no processamento de texto por software de computador, podendo ser uma letra, um número, um sinal de pontuação, um espaço, uma quebra de linha, um caractere chinês, entre outros. string É uma sequência de 0 ou mais caracteres. Texto Ou seja, texto, string. Dizer uma determinada string. Combinar Uma expressão regular geralmente se refere a uma parte (ou várias partes) de uma string que pode satisfazer as condições impostas pela expressão.

Introdução

A melhor maneira de aprender expressões regulares é começar com exemplos, entender os exemplos e, em seguida, modificar e experimentar por conta própria. Abaixo estão vários exemplos simples, acompanhados de explicações detalhadas.

Suponha que você esteja procurando em um romance em inglês. hi Você pode usar expressões regulares. hi

Este é quase o regex mais simples, que pode corresponder exatamente a strings como: Formado por dois caracteres, o primeiro é h e o segundo é i. Normalmente, as ferramentas que lidam com expressões regulares oferecem uma opção de ignorar maiúsculas e minúsculas. Se essa opção estiver selecionada, ela pode corresponder. hi , HI , Hi , hI Qualquer uma das quatro situações.

Infelizmente, muitas palavras contêm hi esses dois caracteres consecutivos, como him , history , high Espera. Usar. hi Para procurar, aqui dentro. hi Também será encontrado. Se precisar. Encontre com precisão a palavra "hi". Deveríamos usar. \bhi\b

\b É um código especial definido pela expressão regular (ok, algumas pessoas chamam isso de). caractere especial, metacharacter representa O início ou o fim da palavra, ou seja, o ponto de divisão da palavra. Embora normalmente as palavras em inglês sejam separadas por espaços, pontuação ou quebras de linha, no entanto, \b não corresponde a nenhum dos caracteres separadores dessas palavras, ele Apenas corresponder a uma posição.

Se o que você está procurando é Logo atrás do hi, há uma Lucy. você deveria usar \bhi\b.*\bLucy\b

Se precisar de uma expressão mais precisa, \b Combine essa posição: o caractere anterior e o caractere posterior não são todos (um é, um não é ou não existe). \w

Aqui, o ponto (.) é outro metacaractere que corresponde. Qualquer caractere, exceto o caractere de nova linha. . *São também metacaracteres, mas o que representam não é um caractere, nem uma posição, mas sim uma quantidade - eles especificam. * O conteúdo anterior pode ser repetido continuamente quantas vezes forem necessárias para que toda a expressão seja correspondida. Portanto, * Juntos significa uma quantidade arbitrária de caracteres que não contêm quebras de linha. Agora. \bhi\b. * \bLucy\b O significado é bem claro: hi Lucy

Se usarmos outros metacaracteres ao mesmo tempo, podemos construir expressões regulares mais poderosas. Por exemplo, o seguinte exemplo:

0\d\d-\d\d\d\d\d\d\d\d Combinar uma string assim: Começando com 0, seguido por dois dígitos, então um hífen "-", e finalmente 8 dígitos. (ou seja, os números de telefone da China. Claro, este exemplo só pode corresponder a casos com código de área de 3 dígitos).

换行符就是'\n',ASCII编码为10(十六进制 0x0A ) de caracteres.

aqui \d É um novo metacaractere, que corresponde. Um dígito (0, ou 1, ou 2, ou...) )- Não é um metacaractere, apenas corresponde a ele mesmo - o hífen (ou traço, ou linha média, ou como você preferir chamá-lo).

Para evitar tantas repetições irritantes, também podemos escrever essa expressão assim: 0\d{2}-\d{8} Aqui. \d 后面的{ 2 }({ 8 }) significa "anterior" ou "antes". \d Deve haver uma correspondência contínua repetida 2 vezes (8 vezes).

Teste de expressão regular

Se você não acha que expressões regulares são difíceis de ler e escrever, ou você é um gênio, ou você não é deste planeta. A sintaxe das expressões regulares é muito complicada, mesmo para aqueles que as usam com frequência. Devido à dificuldade de leitura e escrita e à propensão a erros, é muito necessário encontrar uma ferramenta para testar expressões regulares.

Outras ferramentas de teste disponíveis:

As diferenças nos detalhes das expressões regulares em diferentes ambientes são significativas. Este tutorial aborda o comportamento das expressões regulares no Microsoft .Net Framework 4.0, portanto, recomendo a ferramenta que desenvolvi para .Net. Testador de expressões regulares Por favor, consulte as instruções nesta página para instalar e executar o software.

Abaixo está uma captura de tela do funcionamento do Regex Tester:

regex_tester

metacaractere

Agora você já conhece alguns caracteres especiais muito úteis, como \b , . , * , e também \d Na expressão regular, há mais caracteres especiais, como \s Combinar Qualquer caractere em branco, incluindo espaços, tabulações (Tab), quebras de linha, espaços em branco de largura total em chinês, etc. \w Combinar letras, números, sublinhados ou caracteres chineses, etc.

Vamos ver mais exemplos a seguir:

\ba\w * \b Correspondência com letras a Palavra inicial - Começa com uma determinada palavra. \b ), e depois as letras a , seguido de uma quantidade arbitrária de letras ou números ( \w * ), por fim, no final da palavra ( \b )。

O tratamento especial para caracteres chineses/汉字 é suportado pelo mecanismo de expressões regulares fornecido pelo .Net; para informações específicas em outros ambientes, consulte a documentação relevante.

Certo, agora vamos falar sobre o que significa uma palavra em expressões regulares: é uma sequência contínua de pelo menos um \w. De fato, isso não tem muito a ver com as milhares de coisas com o mesmo nome que precisamos decorar ao aprender inglês :)

\d+ Combinar 1 ou mais dígitos contínuos Aqui. + é e * Caracteres especiais semelhantes, a diferença é que * Correspondência repetida qualquer número de vezes (possivelmente 0 vezes), enquanto + então corresponde Repetir uma vez ou mais.

\b\w{6}\b Combinar palavra com exatamente 6 caracteres

Código Explicação
. Correspondência de qualquer caractere, exceto a quebra de linha.
\w Corresponder letras, números, sublinhados ou caracteres chineses.
\s Corresponder a qualquer caractere em branco
\d Correspondência de números
\b Combinar o início ou o fim da palavra.
^ Correspondência do início da string
$ Correspondência do final da string

metacaractere ^ & $ Todos correspondem a uma posição, isso e \b É um pouco semelhante. ^ Correspondência com o início da string que você deseja procurar, $ Correspondência de final. Esses dois códigos são muito úteis para validar o conteúdo de entrada, por exemplo, se um site exigir que o número QQ que você preenche deve ter entre 5 e 12 dígitos, você pode usar: ^\d{5,12}$

Aqui está { 5,12 } e { mencionados anteriormente 2 } é semelhante, apenas { 2 } correspondência Só pode repetir duas vezes, nem mais nem menos. ,{ 5,12 } então é O número de repetições não pode ser inferior a 5 vezes nem superior a 12 vezes. Caso contrário, não corresponderá.

Os mecanismos de expressões regulares geralmente oferecem um método para "testar se uma string específica corresponde a uma expressão regular", como no JavaScript. RegExp.test() Método ou método Regex.IsMatch() no .NET. Aqui, a correspondência refere-se a se há alguma parte da string que corresponde à regra da expressão. Se não usar ^ e $ A respeito de \d{5,12} Nesse sentido, usar esse método só garante que a string contém números consecutivos de 5 a 12 e não apenas uma string inteira de 5 a 12 dígitos.

Porque foi utilizado ^ e $ Portanto, toda a string de entrada deve ser usada para e \d{5,12} Para combinar, ou seja, toda a entrada deve ser 5 a 12 números Portanto, se o número QQ inserido corresponder a essa expressão regular, então estará em conformidade com os requisitos.

Assim como a opção de ignorar maiúsculas e minúsculas, algumas ferramentas de processamento de expressões regulares também possuem uma opção para tratar múltiplas linhas. Se essa opção estiver selecionada, ^ e $ o significado se tornou Combinar o início e o fim da linha.

Escape de caracteres

Se você quiser encontrar os metacaracteres em si, como por exemplo ., ou *, surgem problemas: você não pode especificá-los, pois eles serão interpretados de outra forma. Nesse caso, você deve usar \ para cancelar o significado especial desses caracteres. Portanto, você deve usar . e \ * Claro, para procurar \ você mesmo, você também precisa usar. \ \ .

Por exemplo: unibetter \ .com Combinar unibetter.com >C: \ Windows Combinar C:\Windows

Repetir

Você já viu o anterior. * , + , {2} , {2,5} Esses são os modos de correspondência repetida. Abaixo estão todos os quantificadores na expressão regular (códigos de quantidade específica, como *, {5,12}, etc.):

Código/Sintaxe Explicação
* Repetir zero ou mais vezes.
+ Repita uma vez ou mais.
? Repetir zero ou uma vez.
{n} repetir n vezes
{n,} Repetir n vezes ou mais.
{m,m} Repetir de n a m vezes.

Aqui estão alguns exemplos de uso repetido:

Windows\d+ Combinar Windows seguido de um ou mais números

^\w+ Combinar A primeira palavra da linha (ou a primeira palavra da string inteira, dependendo da configuração da opção).

classe de caracteres

Para procurar números, letras ou espaços em branco é muito simples, pois já existem correspondências para esses caracteres. * * o caractere especial, mas se você quiser combinar caracteres que não são caracteres especiais predefinidos * * (Como as vogais a, e, i, o, u), o que deve ser feito?

[muito simples, você só precisa listar eles entre colchetes, como] [aeiou] Apenas combinar. qualquer vogal em inglês [.?!] Combinar Pontuação (. ou ? ou !)

Também podemos especificar um caractere facilmente. escopo como [0-9] O significado de representante e \d É exatamente igual. Um número Da mesma forma. [a-z0-9A-Z_] também é totalmente equivalente a \w (Se considerar apenas o inglês).

Aqui está uma expressão mais complexa: \ (?0\d{2}[) -]?\d{8}

Essa expressão pode corresponder. Vários formatos de números de telefone como (010)88886666 ou 022-22334455 ou 02912345678 Espere. Vamos fazer uma análise disso: primeiro, é um caractere de escape. \ (, pode aparecer 0 ou 1 vez ( ? ), depois é um 0 , seguido por 2 números ( \d{2} ), depois é ) ou - ou espaço um deles, aparece uma vez ou não aparece ( ? ), por fim são 8 dígitos ( \d{8} )。

“(” e “)” também são caracteres especiais, o que vem a seguir Grupo de Festas Então, será mencionado aqui, por isso é necessário usar. Escape

Condições de ramificação

Infelizmente, a expressão anterior também pode corresponder. 010)12345678 ou (022-87654321 esse formato "incorreto". Para resolver esse problema, precisamos usar Condições de ramificação . no regex Condições de ramificação Refere-se a várias regras, se qualquer uma das regras for atendida, deve ser considerada como uma correspondência. O método específico é usar | para separar as diferentes regras. Não entendeu? Sem problemas, veja o exemplo:

0\d{2}-\d{8}|0\d{3}-\d{7} Essa expressão pode. Correspondência de dois tipos de números de telefone separados por hífen: um é o código de área de três dígitos e o número local de oito dígitos (por exemplo, 010-12345678), e o outro é o código de área de quatro dígitos e o número local de sete dígitos (0376-2233445).

\ (0\d{2} ) [- ]?\d{8}|0\d{2}[- ]?\d{8} Essa expressão Correspondência de números de telefone com código de área de 3 dígitos, onde o código de área pode estar entre parênteses ou não, e pode ser separado do número local por um hífen, um espaço ou pode não ter separação. Você pode tentar expandir essa expressão usando condições ramificadas para também suportar códigos de área de 4 dígitos.

\ d{5}-\d{4}|\d{5} Esta expressão é usada para corresponder ao código postal dos Estados Unidos. A regra para os códigos postais americanos é que eles consistem em 5 dígitos ou 9 dígitos separados por um hífen. A razão para dar este exemplo é que ele ilustra um problema: Ao usar condições ramificadas, é importante prestar atenção à ordem dos diferentes critérios. Se você mudar para \ d{5}|\d{5}-\d{4} Nesse caso, ele só corresponderá a códigos postais de 5 dígitos (e aos 5 primeiros dígitos de códigos postais de 9 dígitos). A razão é que, ao testar as condições de ramificação, cada condição será verificada da esquerda para a direita, e se uma ramificação for atendida, as outras condições não serão mais consideradas.

Grupo

Já mencionamos como repetir um único caractere (basta adicionar um quantificador logo após o caractere); mas e se quisermos repetir múltiplos caracteres? Você pode usar parênteses para especificar. sub-expressão (também chamado de Grupo ), então você pode especificar o número de repetições dessa subexpressão, e também pode realizar outras operações na subexpressão (que serão apresentadas mais adiante).

(\d{1,3} . ){3}\d{1,3} É simples. IP Correspondência de endereços Expressão. Para entender esta expressão, analise-a na seguinte ordem: \d{1,3} Correspondência de números de 1 a 3 dígitos. (\d{1,3} \ .){3} Combinar três dígitos mais um ponto final. Grupo ) Repita 3 vezes , por fim adicione. Um número de um a três dígitos. \ d{1,3} )

Infelizmente, isso também irá coincidir. 256.300.888.999 Esse endereço IP que não pode existir. Se pudéssemos usar comparações aritméticas, talvez pudéssemos resolver esse problema de forma simples, mas expressões regulares não oferecem nenhuma funcionalidade matemática, então só podemos usar agrupamentos longos, opções e classes de caracteres para descrever um correto. IP Endereço: ((2[0-4]\d|25[0-5]|[01]?\d\d?) \ .){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)

Os números em um endereço IP não podem ser maiores que 255, não se deixem enganar pelos roteiristas da terceira temporada de "24"...

A chave para entender esta expressão é compreender. 2[0-4]\d|25[0-5]|[01]?\d\d? Aqui eu não vou entrar em detalhes, você mesmo deve ser capaz de analisar seu significado.

antônimo

Às vezes, é necessário procurar caracteres que não pertencem a uma classe de caracteres que pode ser facilmente definida. Por exemplo, quando se deseja encontrar qualquer caractere, exceto números, é necessário usar antônimo

Código/Sintaxe Explicação
\W Correspondência de qualquer caractere que não seja letra, número, sublinhado ou caractere chinês.
\S Corresponde a qualquer caractere que não seja um espaço em branco.
\D Corresponder a qualquer caractere que não seja um dígito.
\B Correspondência não é a posição do início ou do fim da palavra.
[^x] Combinar qualquer caractere exceto x.
[^aeiou] Correspondência de qualquer caractere que não seja uma das letras a, e, i, o, u.

Exemplo: \S+ Correspondência de strings que não contêm espaços em branco.

<a[^> ] +> Combine strings that start with "a" and are enclosed in angle brackets.

citação retroativa

usando parênteses para especificar uma subexpressão, Correspondência do texto deste subexpressão. (O conteúdo capturado por este grupo) pode ser processado ainda mais em expressões ou outros programas. Por padrão, cada grupo terá automaticamente um Número do grupo A regra é: da esquerda para a direita, usando o parêntese esquerdo do grupo como sinal, o primeiro grupo que aparece tem o número 1, o segundo tem o número 2, e assim por diante.

citação retroativa Usado para pesquisar novamente o texto correspondente a um grupo anterior. Por exemplo, \1 representante Texto correspondente ao Grupo 1 Difícil de entender? Veja o exemplo:

\b(\w+)\b\s+\1\b Pode ser usado para combinar palavras repetidas, como go go ou kitty kitty Esta expressão é primeiro uma palavra ou seja Mais de uma letra ou número entre o início e o fim da palavra. (\b(\w+)\b) Essa palavra será capturada no grupo número 1, e depois é 1 ou vários espaços em branco ( \s+ ), finalmente é Conteúdo capturado no grupo 1 (ou seja, a palavra correspondente anterior) \1 )

Hum... na verdade, a alocação dos números do grupo não é tão simples quanto eu acabei de dizer:

  • O grupo 0 corresponde a toda a expressão regular.
  • Na verdade, o processo de alocação de números de grupo deve ser realizado em duas passagens da esquerda para a direita: a primeira passagem aloca números apenas para os grupos não nomeados, enquanto a segunda passagem aloca números apenas para os grupos nomeados – portanto, todos os números dos grupos nomeados são maiores do que os números dos grupos não nomeados.
  • Você pode usar a sintaxe (?:exp) para privar um grupo do direito à atribuição de um número de grupo.

Você também pode especificar subexpressões por conta própria. Nome do grupo Para especificar um nome de grupo para uma subexpressão, use a seguinte sintaxe: ( ? < Word>\w+ )(或者把尖括号换成'也行:( ?'Word'\w+ ), assim se torna \w+ O nome do grupo foi designado como Word Para referenciar esse grupo de forma inversa. Captura do conteúdo, você pode usar \k < Word> , então o exemplo anterior também pode ser escrito assim: \b(? < Word>\w+)\b\s+\k < Word>\b

Ao usar parênteses, há muitas regras gramaticais com finalidades específicas. Abaixo estão listados alguns dos mais comuns:

Já discutimos as duas primeiras gramáticas. A terceira ( ?:exp ) Não mudará a forma como as expressões regulares são tratadas, apenas o conteúdo correspondente a esse tipo de grupo não será capturado em um grupo como nas duas primeiras formas, e não terá um número de grupo. "Por que eu gostaria de fazer isso?" — Boa pergunta, o que você acha?

Zero-width assertion

Os próximos quatro são usados para encontrar coisas antes ou depois de certos conteúdos (mas não incluindo esses conteúdos), ou seja, eles são como \b , ^ , $ assim usado para especificar uma posição, que deve atender a certas condições (ou seja, afirmações), por isso também são chamados de Zero-width assertion É melhor usar exemplos para ilustrar.

(?=exp) também chamado Predicado antecipado de previsão de largura zero. ele/ela Afirmar que a posição após a própria ocorrência pode corresponder à expressão exp. Por exemplo. \b\w+(?=ing\b) , combinar com ing parte anterior da palavra final (exceto ing parte externa) como procurar I'm singing while you're dancing. ele vai corresponder sing e danc

(?<=exp) também chamado Afirmativa de falha após revisão positiva de largura zero. ele/ela Afirmar que a posição anterior à própria ocorrência pode corresponder à expressão exp. Por exemplo ( ?<=\bre)\w+\b vai corresponder a palavras que começam com "re" e a parte posterior (exceto "re") por exemplo, ao procurar reading a book Quando ele corresponde ading

Terrestres, vocês não acham que esses termos são muito complicados e difíceis de lembrar? Eu também sinto o mesmo. Saber que existe algo assim já é suficiente, como se chama, tanto faz! Se uma pessoa não tiver nome, poderá se concentrar em praticar a espada; se um objeto não tiver nome, poderá ser escolhido livremente...

Uma asserção é usada para declarar um fato que deve ser verdadeiro. Em expressões regulares, a correspondência só continuará se a asserção for verdadeira.

Se você deseja adicionar uma vírgula a cada três dígitos em um número muito longo (claro, começando pela direita), você pode procurar as partes onde precisa adicionar vírgulas na frente e no meio. ((?<=\d)\d{3})+\b , use it against. 1234567890 O resultado da busca é 234567890

O exemplo abaixo utiliza ambas as afirmações: (?<=\s)\d+(?=\s) Combinar Números separados por espaços em branco (novamente enfatizando, não incluindo esses espaços em branco)

afirmação negativa de largura zero

Anteriormente, mencionamos como procurar. não é um determinado caractere ou não está em uma determinada classe de caracteres o método de caracteres (antônimo). Mas se apenas quisermos Assegurar que um determinado caractere não apareça, mas sem querer fazer a correspondência. O que fazer então? Por exemplo, se quisermos encontrar uma palavra assim - que contém a letra q, mas que não é seguida pela letra u, podemos tentar assim:

\b\w * q [ ^u ] \w * \b Combinar incluir A letra q que não é seguida pela letra u. a palavra No entanto, se você fizer mais testes (ou se sua mente for aguçada o suficiente para perceber diretamente), você descobrirá que, se a letra q aparecer no final da palavra, como... Iraq , Benq essa expressão dará erro. Isso ocorre porque [^u] Sempre deve corresponder a um caractere, então se q for o último caractere da palavra, o que vem a seguir [ ^u] A correspondência será feita com o delimitador da palavra que vem após "q" (pode ser um espaço, um ponto ou outra coisa qualquer). \w * \b Então, irá corresponder à próxima palavra. \b\w * q [ ^u]\w * \b Pode corresponder a todo. Iraq fighting afirmação negativa de largura zero Pode resolver esse tipo de problema, pois ele só corresponde a uma posição e não a outras. Consumo Qualquer caractere. Agora, podemos resolver esse problema da seguinte maneira: \b\w * q(?!u)\w * \b

Afirmativa antecipada negativa de largura zero. (?!exp) Afirmar que não é possível corresponder à expressão exp após esta posição. Por exemplo: \d{3}(?!\d) Correspondem a três dígitos e isso Um número de três dígitos não pode ser seguido por um número. \b((?!abc)\w)+\b Combinar Não contém strings contínuas. abc a palavra

Da mesma forma, podemos usar (?<!exp) , Afirmativa pós-revisão negativa de largura zero. Venha. Afirmar que a posição anterior não pode corresponder à expressão exp. (?<![a-z])\d{7} Combinar Sete dígitos que não começam com letras minúsculas.

Um exemplo mais complexo: (?<=<(\w+)>). * (?=<\/\1>) Correspondência do conteúdo dentro de tags HTML simples que não contêm atributos. (?<=<(\w+)>) Foi especificado assim. prefixo Palavras entre colchetes angulares. (por exemplo, pode ser) < b>),然后是 .* (qualquer string), termina com um sufixo (?=<\/\1>) . Preste atenção ao sufixo. \/ Isso utiliza a escape de caracteres mencionada anteriormente; \1 é uma citação reversa, referindo-se exatamente a Primeiro grupo capturado anterior (\w+) Conteúdo correspondente, assim se o prefixo for na verdade < b>的话,后缀就是 < /b>了。整个表达式匹配的是 < b>和 < /b>之间的内容(再次提醒,不包括前缀和后缀本身)。

Por favor, analise detalhadamente a expressão. (?<=<(\w+)>). * (?=<\/\1>) Essa expressão representa melhor o verdadeiro propósito das asserções de largura zero.

Comentário

Outra utilização dos parênteses é através da gramática. (?#comment) Por favor, inclua comentários. Por exemplo: 2[0-4]\d(?#200-249)|25 [ 0-5](?#250-255)|[01]?\d\d?(?#0-199)

Para incluir comentários, é melhor ativar a opção "Ignorar espaços em branco no modo de ignorar", assim você pode adicionar espaços, tabulações e quebras de linha livremente ao escrever expressões, e na utilização real, tudo isso será ignorado. Ao ativar esta opção, todo o texto após o # até o final da linha será considerado um comentário e ignorado. Por exemplo, podemos escrever uma expressão anterior assim:

(?<= # Afirmação do prefixo do texto a ser correspondido
<(\w+)> # Encontrar letras ou números entre sinais de menor e maior (ou seja, etiquetas HTML/XML)
) # Fim do prefixo
.* # Correspondência de qualquer texto
(?= # Afirmação para corresponder ao sufixo do texto
<\/\1> # 查找尖括号括起来的内容:前面是一个"/",后面是先前捕获的标签
) # Sufixo final

Ganância e preguiça

Quando uma expressão regular contém quantificadores que aceitam repetições, o comportamento usual é (desde que permita que toda a expressão seja correspondida) fazer a correspondência. O máximo possível. de caracteres. Tomando esta expressão como exemplo: a. * b ele vai corresponder A string mais longa que começa com 'a' e termina com 'b'. Se usado para pesquisar aabab Ele corresponderá à string inteira. aabab Isto é chamado de ganância Combinação.

Às vezes, precisamos mais. preguiça Correspondência, ou seja, correspondência. O mínimo possível. Os caracteres. Os quantificadores dados anteriormente podem ser convertidos para o modo de correspondência preguiçosa, basta adicionar um ponto de interrogação após eles. ? Assim. .*? significa Corresponder a qualquer quantidade de repetições, mas utilizando o mínimo de repetições necessário para que a correspondência total seja bem-sucedida. Agora vamos ver um exemplo da versão preguiçosa:

a. * ?b Combinar A menor string que começa com 'a' e termina com 'b'. Se for aplicado a aabab A frase irá corresponder. aab (primeiro ao terceiro caractere) e ab

Código/Sintaxe Explicação
*? Repita quantas vezes quiser, mas tente repetir o mínimo possível.
+? Repita uma ou mais vezes, mas evite repetições desnecessárias.
?? Repita 0 ou 1 vez, mas repita o mínimo possível.
{n,m}? Repita de n a m vezes, mas com o mínimo de repetições possível.
{n,}? Repita n vezes ou mais, mas tente repetir o mínimo possível.

Por que a primeira correspondência é aab (do primeiro ao terceiro caractere) e não ab (do segundo ao terceiro caractere)? De forma simples, porque a expressão regular tem outra regra cuja prioridade é mais alta do que a regra preguiçosa/gananciosa: a correspondência que começa primeiro tem a maior prioridade — A correspondência que começa mais cedo vence.

Opções de tratamento

Acima foram apresentados algumas opções, como ignorar maiúsculas e minúsculas, tratar múltiplas linhas, etc. Essas opções podem ser usadas para alterar a forma como as expressões regulares são processadas. Abaixo estão as opções de expressões regulares mais comuns no .Net:

Nome Explicação
IgnoreCase (ignorar maiúsculas e minúsculas) A correspondência não diferencia maiúsculas de minúsculas.
Multiline (modo de várias linhas) Alterar ^ e $ o significado, fazendo com que correspondam no início e no final de qualquer linha, e não apenas no início e no final da string inteira. (Neste modo, $ O significado preciso é: combinar a posição anterior e a posição antes do final da string.
Singleline (Modo de linha única) Mude o significado do ponto (.) para que corresponda a cada caractere (incluindo a nova linha \n).
IgnorePatternWhitespace (ignorar espaços em branco) Ignorar espaços em branco não escapados na expressão e ativar por # Anotações marcadas
ExplicitCapture (Captura explícita) Apenas capture grupos que foram explicitamente nomeados.

Uma pergunta que é frequentemente feita é: só é possível usar um modo de várias linhas ou um modo de uma linha ao mesmo tempo? A resposta é: não. Não há relação entre essas duas opções, exceto que seus nomes são semelhantes (a ponto de causar confusão).

Em C#, você pode usar Construtor Regex(String, RegexOptions) 来设置正则表达式的处理选项。如:Regex regex = new Regex(@"\ba\w{6}\b", RegexOptions.IgnoreCase);

Grupo balanceado / correspondência recursiva

Às vezes, precisamos combinar como ( 100 * ( 50 + 15 ) ) Uma estrutura hierárquica aninhada como esta, pode ser utilizada de forma simples. \ (.+ \ ) Isso só corresponderá ao conteúdo entre o parêntese esquerdo mais à esquerda e o parêntese direito mais à direita (aqui estamos discutindo o modo ganancioso, o modo preguiçoso também tem os problemas abaixo). Suponha que o número de parênteses esquerdos e direitos na string original não seja igual, por exemplo, ( 5 / ( 3 + 2 ) ) ) Então, o número de elementos de ambos os lados em nossos resultados de correspondência não será igual. Existe alguma maneira de encontrar o conteúdo entre os parênteses correspondentes mais longos em uma string assim?

A gramática de grupos de equilíbrio apresentada aqui é suportada pelo .Net Framework; outras linguagens/bibliotecas podem não oferecer esse recurso, ou podem suportá-lo, mas exigem o uso de uma sintaxe diferente.

Para evitar ( e \ ( Vamos confundir completamente sua mente, e vamos usar colchetes angulares em vez de parênteses. Agora nossa pergunta se torna como colocar xx aa> yy Como capturar o conteúdo dentro dos pares de colchetes angulares mais longos em uma string assim?

Aqui, é necessário usar a seguinte construção gramatical:

  • (?'group') Nomeie o conteúdo capturado como grupo e empurre-o. Pilha

  • (?'-group') Desempilhe o conteúdo capturado chamado "group", que foi o último a ser inserido na pilha. Se a pilha estava vazia, a correspondência deste grupo falha.

  • (?(group)yes|no) Se houver um conteúdo capturado chamado "group" na pilha, continue correspondendo à parte "yes" da expressão; caso contrário, continue correspondendo à parte "no".

  • (?!) A afirmação antecipada negativa de largura zero falha sempre ao tentar fazer uma correspondência, pois não há expressão sufixa.

    我们需要做的是每碰到了左括号,就在压入一个"Open",每碰到一个右括号,就弹出一个,到了最后就看看堆栈是否为空--如果不为空那就证明左括号比右括号多,那匹配就应该失败。正则表达式引擎会进行回溯(放弃最前面或最后面的一些字符),尽量使整个表达式得到匹配。

如果你不是一个程序员(或者你自称程序员但是不知道堆栈是什么东西),你就这样理解上面的三种语法吧:第一个就是在黑板上写一个"group",第二个就是从黑板上擦掉一个"group",第三个就是看黑板上写的还有没有"group",如果有就继续匹配yes部分,否则就匹配no部分。

Uma das aplicações mais comuns de grupos balanceados é a correspondência de HTML. O exemplo abaixo pode corresponder a aninhamentos. < div>标签: <div [ ^>] * > [ ^<>]*(((?'Open'] * >) [ ^<>] * )+((?'-Open') [ ^<>] * )+) * (?(Open)(?!)) < /div>

O que mais não foi mencionado?

Já foram descritos muitos elementos para construir expressões regulares, mas ainda há muitos que não foram mencionados. Abaixo está uma lista de alguns elementos não mencionados, incluindo a sintaxe e uma breve explicação. Você pode encontrar referências mais detalhadas na internet para aprendê-los - quando precisar usá-los. Se você instalou a Biblioteca MSDN, também pode encontrar a documentação detalhada sobre expressões regulares no .NET lá.

Código/Sintaxe Explicação
\a caractere de alarme (imprimir isso faz o computador emitir um beep)
\b Normalmente é a posição de separação das palavras, mas se for usado dentro de uma classe de caracteres, representa um retrocesso.
\t Tabulação
\r Enter
\v Tabulação vertical
\f quebra de página
\n quebra de linha
\e Escape
\0nn O caractere cujo código octal é nn na tabela ASCII.
\xnn O caractere com código hexadecimal nn na tabela ASCII.
\unnnn O caractere com o código hexadecimal nnnn no código Unicode.
\cN Caracteres de controle ASCII. Por exemplo, \cC representa Ctrl+C.
\A Início da string (semelhante a ^, mas não afetado pela opção de múltiplas linhas)
\Z Fim da string ou fim da linha (não afetado pela opção de processamento de várias linhas)
\z Fim da string (semelhante a $, mas não afetado pela opção de várias linhas)
\G Início da pesquisa atual
\p{name} Classe de caracteres nomeada como name no Unicode, por exemplo, \p{IsGreek}
(?>exp) expressão gananciosa
(? < x> - < y>exp) Grupo de equilíbrio
(?im-nsx:exp) Alterar opções de processamento na subexpressão exp.
(?im-nsx) Alterar as opções de processamento para a parte que vem após a expressão.
(?(exp)yes|no) Trate exp como uma afirmação positiva de largura zero. Se puder haver uma correspondência nessa posição, use yes como a expressão deste grupo; caso contrário, use no.
(?(exp)yes) Da mesma forma, apenas use expressões vazias como não.
(?(name)yes|no) Se o grupo nomeado como name capturou conteúdo, use yes como expressão; caso contrário, use no.
(?(name)yes) Da mesma forma, apenas use expressões vazias como não.

Entrar em contato com o autor

好吧,我承认,我骗了你,读到这里你肯定花了不止30分钟.相信我,这是我的错,而不是因为你太笨.我之所以说"30分钟",是为了让你有信心,有耐心继续下去.既然你看到了这里,那证明我的阴谋成功了.被忽悠的感觉很爽吧?

Se você deseja fazer uma reclamação sobre mim, ou acha que eu poderia enganar de forma mais habilidosa, ou tem qualquer outra questão, sinta-se à vontade para vir. Meu blog Deixe-me saber.

Recursos online e referências bibliográficas deste artigo.

Você usou recentemente:

Coleção Menu QQ