Referensi kembali tidak valid menggunakan grep

9

Jadi saya mencoba menemukan kata-kata 6 huruf yang terdiri dari satu karakter yang diulang tiga kali diikuti oleh karakter lain yang diulang tiga kali. Misalnya aaabbbatau oookkk.

Aku sedang mencoba:

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

Pertama, apakah regex itu benar? Kedua mengapa saya mengerti grep: Invalid back reference?

Sorotan Pabrik
sumber
1
Tolong jelaskan apa yang harus Anda cocokkan. Regex Anda tidak benar sehingga saya tidak mengerti apa yang Anda cari. Apakah Anda mencari kata-kata yang terdiri dari 3 pengulangan dari satu karakter dan kemudian tiga pengulangan dari yang lain? Atau apakah Anda juga ingin mencocokkan aaabbbfoobar? Bagaimana dengan aaaabbb? Idealnya, tunjukkan kepada kami beberapa contoh input dan output yang Anda inginkan.
terdon
1
Referensi balik harus merujuk ke sesuatu, dan Anda belum menentukan apa itu sesuatu. Biasanya Anda mengelompokkan ekspresi menggunakan tanda kurung untuk melakukannya. Misalnya: grep -E '([a-z]{2})([0-9]{2})\2\1'akan cocok aa9999aa.
muru
@terdon Apakah Anda mencari kata-kata yang terdiri dari 3 repetisi dari satu karakter dan kemudian tiga repetisi dari yang lain? Iya. Atau Anda juga ingin mencocokkan aaabbbfoobar? Tidak. Hanya kata-kata seperti oookkk(tidak lebih dari 6 karakter) BUKAN kata-kata yang mengandung oookkksepertioookkkfoobar
Sorotan Pabrik
@ HighlightFactory OK, dalam hal ini gunakan grep -wcontoh yang saya berikan dalam jawaban saya.
terdon
Satu hal lagi, apakah Anda juga ingin mencocokkan aaaaaaatau apakah Anda memerlukan setidaknya dua karakter yang berbeda? Silakan pertimbangkan memberi kami contoh input dan output yang diinginkan.
terdon

Jawaban:

12

Tidak, itu tidak benar. Saya tidak tahu apa yang \1{3}seharusnya tetapi itulah yang menyebabkan masalah Anda. Jika Anda ingin menemukan garis yang berisi tiga karakter berulang yang diikuti oleh tiga karakter berulang lainnya, Anda dapat menggunakan ini:

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

The \1mengacu pertama ditangkap kelompok. Anda dapat menangkap grup dengan menggunakan tanda kurung. Kemudian, \1adalah kelompok pertama seperti itu dan \2yang kedua dan seterusnya. Karena Anda tidak memiliki grup yang ditangkap, grepmengeluh tentang referensi yang tidak valid karena tidak ada referensi. Jadi, dalam regex di atas, tanda kurung menangkap kedua kelompok. Kemudian, Anda inginkan {2}dan bukan {3}karena pertandingan awal juga dihitung.

Anda tidak menentukan apakah Anda perlu kecocokan untuk menjadi kata atau apakah Anda juga ingin mencocokkan dalam kata-kata. Jika Anda ingin seluruh kata cocok (dan mengecualikan hal-hal seperti aaaabbb, gunakan ini sebagai gantinya:

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

Untuk mencetak hanya bagian yang cocok dari baris (kata) dan bukan seluruh baris, gunakan (GNU grep saja):

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