Estou cansado de sempre tentar adivinhar, se devo escapar de caracteres especiais como ' ()[]{}|
' etc. ao usar muitas implementações de regexps.
É diferente com, por exemplo, Python, sed, grep, awk, Perl, renomear, Apache, find e assim por diante. Existe algum conjunto de regras que diga quando devo e quando não devo escapar de caracteres especiais? Depende do tipo de regexp, como PCRE, POSIX ou regexps estendidos?
escape()
" para permitir o uso de seqüências arbitrárias como partes de regex.Respostas:
Quais caracteres você deve e quais não deve escapar realmente dependem do sabor da expressão regular com a qual você está trabalhando.
Para PCRE e a maioria dos outros tipos de sabores compatíveis com Perl, escape dessas classes de caracteres externas:
e estas classes de personagem internas:
Para regex estendido POSIX (ERE), escape destas classes de caracteres externas (o mesmo que PCRE):
Escapar de qualquer outro caractere é um erro no POSIX ERE.
Dentro das classes de caracteres, a barra invertida é um caractere literal nas expressões regulares do POSIX. Você não pode usá-lo para escapar de nada. Você precisa usar "posicionamento inteligente" se quiser incluir metacaracteres da classe de caracteres como literais. Coloque o ^ em qualquer lugar, exceto no início, o] no início e - no início ou no final da classe de personagem para corresponder literalmente a eles, por exemplo:
Nas expressões regulares regulares do POSIX (BRE), esses são metacaracteres dos quais você precisa escapar para suprimir seu significado:
Escapar parênteses e colchetes nos BREs dá a eles o significado especial que suas versões sem escape têm nos EREs. Algumas implementações (por exemplo, GNU) também dão um significado especial a outros caracteres quando escapados, como \? e +. Escapar de um caractere diferente de. ^ $ * () {} Normalmente é um erro nos BREs.
Dentro das classes de personagem, os BREs seguem a mesma regra dos EREs.
Se tudo isso fizer sua cabeça girar, pegue uma cópia do RegexBuddy . Na guia Criar, clique em Inserir token e, em seguida, literal. O RegexBuddy adicionará escapes conforme necessário.
fonte
/
não é um metacaractere em nenhum dos sabores de expressões regulares que eu mencionei, portanto, a sintaxe da expressão regular não requer escapamento. Quando uma expressão regular é citado como um literal em uma linguagem de programação, em seguida, as regras de cordas ou regex formatação de que a linguagem pode exigir/
ou"
ou'
a ser escapou, e podem até mesmo exigir `\` a ser duplamente escapou.Sabores RegEx modernos (PCRE)
Inclui C, C ++, Delphi, EditPad, Java, JavaScript, Perl, PHP (preg), PostgreSQL, PowerGREP, PowerShell, Python, REALbasic, Real Studio, Ruby, TCL, VB.Net, VBScript, wxWidgets, XML Schema, Xojo, XRegExp.
A compatibilidade do PCRE pode variar
Qualquer lugar:
. ^ $ * + - ? ( ) [ ] { } \ |
Sabores RegEx herdados (BRE / ERE)
Inclui awk, ed, egrep, emacs, GNUlib, grep, PHP (ereg), MySQL, Oracle, R, sed.
O suporte PCRE pode ser ativado em versões posteriores ou usando extensões
ERE / awk / egrep / emacs
Fora de uma classe de personagem:
. ^ $ * + ? ( ) [ { } \ |
Dentro de uma classe de personagem:
^ - [ ]
BRE / ed / grep / sed
Fora de uma classe de caracteres:
. ^ $ * [ \
Dentro de uma classe de caracteres:
^ - [ ]
Para literais, não escape:
+ ? ( ) { } |
Para o comportamento regular da expressão regular, escape:
\+ \? \( \) \{ \} \|
Notas
\xFF
] -
é necessário apenas escapar dentro de uma classe de personagem, mas eu os mantive em uma única lista para simplificar"(\")(/)(\\.)"
versus/(")(\/)(\.)/
em JavaScript)fonte
-
ou]
deve ser escapado fora das classes de personagens. POSIX (BRE / ERE) não possui um caractere de escape nas classes de caracteres. O sabor do regex no RTL do Delphi é realmente baseado no PCRE. Python, Ruby e XML têm seus próprios sabores que estão mais próximos do PCRE do que dos sabores POSIX.Infelizmente, não existe realmente um conjunto de códigos de escape, pois isso varia de acordo com o idioma que você está usando.
No entanto, manter uma página como a Página de Ferramentas de Expressão Regular ou esta Folha de dicas sobre expressões regulares pode ajudar bastante a filtrar rapidamente as coisas.
fonte
\<
e\>
são limites de palavras, o que é verdadeiro apenas (AFAIK) na biblioteca de expressões regulares Boost. Mas em outro lugar ele diz<
e>
são metacaracteres e deve ser escapado (com\<
e\>
) para corresponder-los literalmente, o que não é verdade em qualquer saborInfelizmente, o significado de coisas como (e \ (são trocados entre as expressões regulares do estilo Emacs e a maioria dos outros estilos). Portanto, se você tentar escapar deles, poderá estar fazendo o oposto do que deseja.
Então você realmente precisa saber qual estilo você está tentando citar.
fonte
O POSIX reconhece várias variações em expressões regulares - expressões regulares básicas (BRE) e expressões regulares estendidas (ERE). E mesmo assim, existem peculiaridades por causa das implementações históricas dos utilitários padronizados pelo POSIX.
Não existe uma regra simples para quando usar qual notação, ou mesmo qual notação um determinado comando usa.
Confira o livro Master Expressões Regulares de Jeff Friedl .
fonte
Realmente não existe. existem cerca de meio zilhão de diferentes sintaxes de expressões regulares; eles parecem se resumir a Perl, EMACS / GNU e AT&T em geral, mas estou sempre ficando surpreso também.
fonte
Às vezes, o escape simples não é possível com os caracteres que você listou. Por exemplo, o uso de uma barra invertida para escapar de um suporte não funcionará no lado esquerdo de uma string de substituição no sed, a saber
Como costumo usar apenas uma definição simples de classe de caractere, a expressão acima se torna
que eu acho que funciona para a maioria das implementações de expressões regulares.
As classes de caracteres BTW são componentes de regexp de baunilha, portanto, eles tendem a funcionar na maioria das situações em que você precisa de caracteres de escape nos regexps.
Edit: Após o comentário abaixo, pensei em mencionar o fato de que você também deve considerar a diferença entre autômatos de estados finitos e autômatos de estados não-finitos ao analisar o comportamento da avaliação regexp.
Você pode consultar o "livro brilhante", também conhecido como Effective Perl ( link higienizado da Amazon ), especificamente o capítulo sobre expressões regulares, para ter uma idéia da diferença nos tipos de avaliação do mecanismo de expressão regular.
Nem todo o mundo é um PCRE!
De qualquer forma, as expressões regulares são tão desajeitadas em comparação com o SNOBOL ! Agora esse foi um curso de programação interessante! Junto com o de Simula .
Ah, as alegrias de estudar na UNSW no final dos anos 70! (-:
fonte
Para o PHP, "é sempre seguro preceder um não alfanumérico com" \ "para especificar que ele representa". - http://php.net/manual/en/regexp.reference.escape.php .
Exceto se for um "ou '.: /
Para escapar de variáveis de padrão de expressão regular (ou variáveis parciais) no PHP, use preg_quote ()
fonte
Para saber quando e o que escapar sem tentativas é necessário entender com precisão a cadeia de contextos pela qual a cadeia passa. Você especificará a string do lado mais distante ao seu destino final, que é a memória manipulada pelo código de análise regexp.
Esteja ciente de como a cadeia de caracteres na memória é processada: se pode ser uma cadeia simples dentro do código ou uma cadeia inserida na linha de comando, mas a pode ser uma linha de comando interativa ou uma linha de comando declarada dentro de um arquivo de script de shell ou dentro de uma variável na memória mencionada pelo código, ou um argumento (string) por meio de avaliação adicional, ou uma string contendo código gerado dinamicamente com qualquer tipo de encapsulamento ...
Cada um desse contexto atribuiu alguns caracteres com funcionalidade especial.
Quando você deseja passar o caractere literalmente sem usar sua função especial (local para o contexto), esse é o caso em que você precisa escapá-lo, para o próximo contexto ... que pode precisar de outros caracteres de escape que adicionalmente precisam ser escapou no (s) contexto (s) anterior (es). Além disso, pode haver coisas como codificação de caracteres (o mais insidioso é utf-8, porque se parece com ASCII para caracteres comuns, mas pode ser opcionalmente interpretado mesmo pelo terminal, dependendo de suas configurações, para que possa se comportar de maneira diferente, e então pelo atributo de codificação HTML. / XML, é necessário entender o processo com precisão.
Por exemplo, uma regexp na linha de comando começando com
perl -npe
, precisa ser transferido para um conjunto de chamadas do sistema exec conectando como canal que o arquivo manipula, cada uma dessas chamadas do sistema exec apenas possui uma lista de argumentos que foram separados por espaços (sem escape), e possivelmente pipes (|) e redirecionamento (> N> N> & M), parênteses, expansão interativa*
e?
,$(())
... (tudo isso são caracteres especiais usados pelo * sh que podem parecer interferir no caractere da expressão regular no próximo contexto, mas são avaliados em ordem: antes da linha de comando. A linha de comando é lida por um programa como bash / sh / csh / tcsh / zsh, essencialmente dentro de aspas duplas ou aspas simples, o escape é mais simples, mas não é necessário citar uma string na linha de comando, porque na maioria das vezes o espaço deve ser prefixado com barra invertida e as aspas são não é necessário deixar disponível a funcionalidade de expansão para os caracteres * e?, mas isso é analisado em contextos diferentes das citadas.Então, quando a linha de comando é avaliada, o regexp obtido na memória (não gravado na linha de comando) recebe o mesmo tratamento que estaria em um arquivo de origem.Para regexp, existe um contexto de conjunto de caracteres entre colchetes [],A expressão regular perl pode ser citada por um grande conjunto de caracteres não alfanuméricos (por exemplo, m // ou m: / better / for / path: ...).Você tem mais detalhes sobre caracteres em outra resposta, que são muito específicos para o contexto final da expressão regular. Como observei, você mencionou que encontra o escape da regexp com tentativas, provavelmente porque o contexto diferente tem um conjunto de caracteres diferente que confunde sua memória de tentativas (geralmente barra invertida é o caractere usado nesse contexto diferente para escapar de um caractere literal em vez de sua função )
fonte
https://perldoc.perl.org/perlre.html#Quoting-metacharacters e https://perldoc.perl.org/functions/quotemeta.html
Na documentação oficial, esses caracteres são chamados de metacaracteres. Exemplo de citação:
fonte
Para Ionic (Texto Dactilografado), é necessário dobrar a barra para escapar dos caracteres. Por exemplo (isso corresponde a alguns caracteres especiais):
Preste atenção a esses
] [ - _ . /
personagens. Eles precisam ser cortados duas vezes. Se você não fizer isso, terá um erro de tipo no seu código.fonte