Referência retroativa inválida usando grep

9

Então, eu estou tentando encontrar palavras de 6 letras que consistem em um caractere repetido três vezes, seguido por outro caractere repetido três vezes. Por exemplo aaabbbou oookkk.

Eu estou tentando:

grep -E "[a-z]\1{3}\S[a-z]\1{3}" filename

Primeiro, o regex está correto? Segundo, por que estou recebendo grep: Invalid back reference?

Fábrica de Destaques
fonte
1
Por favor, explique o que exatamente você precisa combinar. Seu regex não está correto, então não consigo entender o que você procura. Você está procurando palavras que consistem em 3 repetições de um caractere e depois em três repetições de outro? Ou você também quer combinar aaabbbfoobar? Que tal aaaabbb? Idealmente, mostre-nos alguns exemplos de entrada e a saída desejada.
terdon
1
Uma referência anterior deve se referir a algo, e você não especificou o que é isso. Geralmente, você agrupa uma expressão usando parênteses para fazer isso. Por exemplo: grep -E '([a-z]{2})([0-9]{2})\2\1'corresponderia aa9999aa.
Muru
@terdon Você está procurando palavras que consistem em 3 repetições de um caractere e depois em três repetições de outro? Sim. Ou você também quer combinar aaabbbfoobar? Não. Somente palavras como oookkk(não mais que 6 caracteres) NÃO são palavras que contêm oookkkcomooookkkfoobar
Highlights Factory
@HighlightsFactory OK, nesse caso, use o grep -wexemplo que dei na minha resposta.
terdon
Mais uma coisa, você também quer combinar aaaaaaou precisa de pelo menos dois caracteres diferentes? Por favor, considere nos dar um exemplo de entrada e saída desejada.
terdon

Respostas:

12

Não, não está correto. Não tenho idéia do que \1{3}deveria ser, mas é isso que está causando problemas. Se você deseja encontrar linhas que contêm três caracteres repetidos seguidos por outros três caracteres repetidos, você pode usar isso:

grep -E '([a-z])\1{2}([a-z])\2{2}'

O \1refere-se ao primeiro grupo capturado . Você pode capturar grupos usando parênteses. Então, \1é o 1º desse grupo e \2é o segundo e assim por diante. Como você não tinha grupos capturados, grepestava reclamando de uma referência inválida, pois não tinha nada a que se referir. Portanto, no regex acima, os parênteses estão capturando os dois grupos. Então, você quer {2}e não, {3}pois a correspondência inicial também é contada.

Você não especifica se precisa que a correspondência seja uma palavra ou se deseja também corresponder às palavras. Se você deseja que a palavra inteira corresponda (e exclua coisas como aaaabbb, use isso:

grep -wE '([a-z])\1{2}([a-z])\2{2}'

Para imprimir apenas a parte correspondente da linha (a palavra) e não a linha inteira, use (somente grep GNU):

grep -owE '([a-z])\1{2}([a-z])\2{2}'
terdon
fonte