[specification] corresponde a um elemento de intercalação (pode ser um caractere ou sequência de caracteres conforme definido no algoritmo de intercalação da localidade (por exemplo, em locais húngaros em sistemas GNU, dzs é um elemento de intercalação que classifica em algum lugar entre d e e )) no conjunto especificado .
Essa especificação pode incluir
- varia como
a-z(ou[.dzs.]-z) para agrupar elementos que agrupam entreaez(observe que geralmente inclui abcdefghijklmnoprstuvwxyz, mas na maioria das localidades, inclui muito mais). Além disso, como POSIX não é especificado para locais diferentes dos locais POSIX, o quanto esses intervalos são baseados na ordem de agrupamento varia significativamente entre as implementações. - caracteres individuais ou elementos de agrupamento (
x,[.dsz.]) - Classes de caracteres POSIX
[:alpha:],[:digit:] - classes equivalentes como
[=e=]para todos os elementos de intercalação que possuem o mesmo peso de classificação primário quee(pode incluir itens comoé)
Portanto, por exemplo, [acd[=e=]h-k[:digit:][.dzs.]] corresponde a um elemento de intercalação, desde que seja a , c , d , dzs ou equivalente a e ou agrupamentos entre h e k ou é classificado como dígito .
E se a especificação começar com ^ , ela ainda corresponderá a um elemento de intercalação, mas com o conjunto complementado. Isso é qualquer elemento de agrupamento, mas os especificados.
Portanto, [^a-z] corresponde a qualquer elemento de intercalação que não agrupe entre a e z . Por exemplo, provavelmente corresponderia a 1 e ẑ , possivelmente a X ou DSZ , dependendo da localidade e da implementação grep , mas não da a , x nor z e provavelmente não em é .
Portanto, grep '[^a-z]\{22\}' corresponde a linhas que contêm uma sequência de 22 elementos de comparação que agrupam antes de a ou depois de z .
Enquanto grep -v '[a-z]\{22\}' corresponde a linhas que não contêm uma sequência de 22 elementos de agrupamento, agrupados entre a e z .
A correspondência do mesmo sem -v é quase impossível de implementar, você precisaria corresponder em linhas que não contenham mais de 21 [a-z] elementos de intercalação entre dois [^a-z] elemento. Mas se a localidade suportar elementos de agrupamento de vários caracteres, isso não é realmente possível. Por exemplo, nessas localidades húngaras, [a-z] corresponde a dsz , mas também a d , s e z , então você verá que, [a-z]{0,21} corresponderá a dszxxxyyyxxxyyyxxxyyyx , mas também [a-z]{22} .
Para locais que não possuem elementos de classificação de vários caracteres, você pode fazer algo como:
grep '^[^a-z]*\([a-z]\{1,21\}[^a-z]\{1,\}\)*[a-z]\{0,21\}$'
Agora, também há algumas implementações grep que suportam sintaxes regulares mais avançadas com opções que possuem algum operador negação .
Por exemplo, a implementação GNU ou ast-open das expressões regulares grep suportam perl-like (usando libpcre no GNU grep, própria implementação do ast-open para ast-open grep) com a opção -P que tem um (?!pattern) operador de look-ahead negativo .
(?!pattern) corresponde à largura zero em qualquer ponto da cadeia de assunto, desde que o padrão não corresponda a partir de lá. Então, pode-se usar:
grep -P '^(?!.*[a-z]{22})'
para corresponder no início da linha, desde que não seja seguido por nenhum número de caracteres e 22 [a-z] s. No entanto, observe que no PCRE (não em ast-open), [a-z] corresponde apenas a abcdefghijklmnopqrstuvwxyz, independentemente da localidade.
o ast-open também usa uma opção -X para o que eles chamam de expressões regulares aumentadas . Esses regex aumentados têm um operador ! que nega as coisas. x! corresponderia a algo diferente de x (incluindo a string vazia).
Portanto, com ast-open grep , você também pode:
grep -X '^(.*[a-z]{22}.*)!$'