Eu uso o seguinte regex para encontrar endereços de e-mail:
echo "[email protected]" | awk '/^([a-zA-Z0-9_-.\+]+)@([a-zA-Z0-9_-.]+).([a-zA-Z]{2,5})$/ {print $0}'
Mas retorna o erro:
awk: cmd. line:1: error : tent of \{\}
Eu uso o seguinte regex para encontrar endereços de e-mail:
echo "[email protected]" | awk '/^([a-zA-Z0-9_-.\+]+)@([a-zA-Z0-9_-.]+).([a-zA-Z]{2,5})$/ {print $0}'
Mas retorna o erro:
awk: cmd. line:1: error : tent of \{\}
Responda:
Explicação: O caractere
-
é ambíguo na posição em que você o coloca, pois pode representar um intervalo. Movê-lo para o início do regexp, ou escapá-lo, funciona muito bem.Mais informações: Verifique seus regexes neste site útil quando estiver em dúvida.
Conforme apontado corretamente por Isaac , o último ponto na expressão não faz o que você provavelmente pensa que faz:
.
representa qualquer caractere, e você deve escapar se quiser que signifique um ponto literal\.
Outras otimizações incluem não escapar caracteres entre colchetes, pois isso é desnecessário. Estou apontando para
\+
o primeiro conjunto de caracteres, e tenho que agradecer a Isaac novamente por detectar isso!Mais uma coisa que está além de mim é por que você usaria todos esses colchetes
()
.Além de corrigir o uso
-
e sugerir algumas pequenas melhorias, o tema subjacente aqui é a oportunidade amplamente discutida de empregar expressões regulares para validar endereços de e-mail. A correspondência correta de qualquer endereço de e-mail é uma tarefa difícil que requer uma expressão muito mais complexa do que se poderia imaginar inicialmente. Uma opção razoável, geralmente encontrada neste e em fóruns semelhantes, é usar o regex mais simples que, espera-se, funcionará com seu conjunto de dados.Versão curta, use isto:
Supondo que a mensagem de erro real seja algo como:
Então, há 4 problemas em sua linha:
O traço (
-
) significa "intervalo de caracteres" e não um traço explícito.O motivo da mensagem de erro é que os dois caracteres ao redor do traço (
-
) dentro do intervalo de caracteres (_
e.
) não estão em ordem (ASCII). O intervalo de caracteres.-_
não gera nenhum erro. Mas estou certo de que você não quer dizer "intervalo de caracteres" (todos os caracteres entre um ponto.
e um sublinhado_
), mas para corresponder a um traço explícito (-
).Para corresponder a um traço explícito dentro de uma "expressão de colchete", você precisa torná-lo o primeiro ou o último caractere do intervalo. Ou
[-…]
,[…-]
. Ou, desanimado, fuja dele\-
. Ou seja, ambos funcionam:Mas não, uma barra invertida não é uma solução geral para tornar um traço explícito. Tentar:
A regex grep (mesmo se estendida:
-E
) não corresponde ao traço.O
+
não é especial dentro de uma "expressão de colchetes", portanto, não precisa escapar (e escapar dentro de "expressões de colchetes" é um mau hábito). Usa isto:Um ponto
.
é um caractere especial que "corresponde a qualquer caractere, exceto nova linha".Como tal, você precisa escapar
\.
ou usar uma "expressão de colchete"[.]
para corresponder explicitamente a um caractere de ponto, use isto:E, finalmente, a "expressão de intervalo" é uma extensão sobre implementações históricas de awk, pode não funcionar em todos os awk's. Isso geralmente "não é um problema", mas se for, você precisará usar:
Mas você provavelmente está usando GNU awk, e a sintaxe correta deve ser:
O hífen
-
é um caractere especial na classe de caracteres ( Bracket Expression ) que especifica o intervalo de caracteres. Se você quiser adicionar literal-
à sua classe de caractere, precisará escapá-lo ou movê-lo para o final ou início (após o^
, se houver) de sua classe de caractere.Qual versão
awk
você está usando?Este comando não dá erro quando eu uso GNU
awk
, embora não produza nenhuma saída.Usá
solaris
awk
-lo produz este erro:Lendo seu
regex
, ele nunca corresponderá a um endereço de e-mail...