[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 entrea
ez
(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}.*)!$'