(grep) Regex agar sesuai dengan karakter non-ASCII?


169

Di Linux, saya memiliki direktori dengan banyak file. Beberapa dari mereka memiliki karakter non-ASCII, tetapi semuanya adalah UTF-8 yang valid . Satu program memiliki bug yang mencegahnya bekerja dengan nama file non-ASCII, dan saya harus mencari tahu berapa banyak yang terpengaruh. Saya akan melakukan ini dengan finddan kemudian melakukan grep untuk mencetak karakter non-ASCII, dan kemudian melakukan a wc -luntuk menemukan nomornya. Tidak harus grep; Saya dapat menggunakan ekspresi reguler standar Unix , seperti Perl , sed , AWK , dll.

Namun, apakah ada ekspresi reguler untuk 'karakter apa pun yang bukan karakter ASCII'?


1
Paul, ya saya bisa menggunakan perl
Rory

/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]
Tinmarino

Jawaban:


310

Ini akan cocok dengan satu karakter non-ASCII:

[^\x00-\x7F]

Ini adalah PCRE ( Ekspresi Reguler Perl Kompatibel Kompatibel ) yang valid .

Anda juga dapat menggunakan singkatan POSIX :

  • [[:ascii:]] - Cocok dengan satu karakter ASCII
  • [^[:ascii:]] - Cocok dengan satu karakter non-ASCII

[^[:print:]] mungkin akan cukup untuk Anda. **


3
@adrianm: Tidak, ^valid di PCRE.
Alix Axel

10
Benar sekali. Namun Anda harus menggunakan pcregrep, bukan grep standar. [^ [: print:]] tidak akan berfungsi jika terminal Anda diatur di UTF8.
Rory

@Rory, mengapa :print:tidak bekerja di terminal UTF8? Ini bekerja untuk saya di pry di terminal UTF8:27.chr =~ /[^[:print:]]/
akostadinov

Ini sangat bagus untuk memperbaiki nama file yang buruk - rename 's/[^\x00-\x7F]//g' *(Anda dapat menggunakannya -nuntuk memeriksa nama-nama yang ok terlebih dahulu).
naught101

Bagaimana cara mencocokkan karakter yang bukan UTF8 dan karakter spesifik lainnya?
CMCDragonkai

37

Tidak, [^\x20-\x7E]bukan ASCII.

Ini ASCII yang asli:

 [^\x00-\x7F]

Jika tidak, ini akan memangkas baris baru dan karakter khusus lainnya yang merupakan bagian dari tabel ASCII!



3

[^\x00-\x7F]dan [^[:ascii:]]kehilangan beberapa byte kontrol sehingga string bisa menjadi pilihan yang lebih baik kadang-kadang. Misalnya cat test.torrent | perl -pe 's/[^[:ascii:]]+/\n/g'akan melakukan hal-hal aneh ke terminal Anda, di mana seperti strings test.torrentakan berperilaku.




2

Anda dapat menggunakan regex ini:

[^\w \xC0-\xFF]

Case ask, opsinya adalah Multiline .


2

Anda tidak benar-benar membutuhkan regex.

printf "%s\n" *[!\ -~]*

Ini akan menunjukkan nama file dengan karakter kontrol di namanya juga, tetapi saya menganggap itu sebagai fitur.

Jika Anda tidak memiliki file yang cocok, glob akan berkembang menjadi sendiri, kecuali jika Anda telah nullglobmenetapkan. (Ekspresi tidak cocok dengan dirinya sendiri, jadi secara teknis, output ini tidak ambigu.)


Terlambat, saya dapat mengamati bahwa ini tidak bekerja dengan benar jika Anda benar-benar memiliki beberapa file yang cocok dengan pola ini. Perilaku di mana pola mencetak sendiri ketika tidak ada kecocokan sedikit mengejutkan tetapi sebenarnya benar. Saya mengedit jawaban untuk mudah-mudahan memperjelas ini.
tripleee

1

Ini ternyata sangat fleksibel dan dapat diperpanjang. $ field = ~ s / [^ \ x00- \ x7F] // g; # dengan demikian semua non ASCII atau item tertentu yang dimaksud dapat dibersihkan. Sangat bagus baik dalam pemilihan atau pra-pemrosesan item yang pada akhirnya akan menjadi kunci hash.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.