notepad ++ panjang regex dalam byte

1

Saya berjuang dengan membuat regex di notepad ++ yang menemukan dan mengganti x jumlah byte dengan apa-apa. Carriage return (0D) menghitung, jumlah feed line (0A).

Ini adalah regex yang saya coba: (0C adalah awal saya, saya menghapus 318 byte setelah 0C bersama dengan 0C)

\x0C(.{318})

Regex ini tidak menemukan apa-apa, katanya tidak ada yang cocok. Saya dapat menemukan \x0C, dan saya dapat menemukan . tetapi saya tidak dapat menemukan .{318} juga . melompati 0x0A dan 0x0D

-wrap sekitar diperiksa.

ekspresi reguler diperiksa.

Ini adalah bagian dari file dalam hex dengan ascii:

0C 30 31 32 27 34 35 36 0D 0A 30 61 32 0D 33 34 0A [snip] 0C 32 0A 0D 35 [etc..]
<ff>0  1  2  '  4  5  6<cr><lf>0  a  2<cr> 3  4<lf>[snip]<ff> 2<lf><cr>5 [etc..]
UpTide
sumber
Jadi, apa masalah Anda dan apa yang tidak berhasil? Seperti apa input dan output Anda sebenarnya?
Seth
1
satu hal yang bisa Anda coba adalah mengonversi file menjadi hex, dan menjalankan regex pada hex, sehingga file tersebut akan terlihat sedikit seperti yang Anda tampilkan, tetapi kemudian Anda tidak melakukan \ x0C Anda melakukan 0C secara harfiah. Caramu, mencari hex misalnya \ x0C dapat bekerja juga jika ascii jadi setiap char adalah byte. Tetapi sertakan file di sini seperti unggah file ke ge.tt dan sertakan tautan dalam pertanyaan Anda. Dan kembali kekhawatiran Anda tentang apakah titik cocok dengan baris baru atau tidak, Anda dapat mengubahnya superuser.com/questions/481276/…
barlop
Kurung bundar berlebihan sehingga Anda dapat menghapusnya. Juga, coba ubah 318 ke angka yang jauh lebih kecil seperti 3, lihat apakah itu cocok dengan apa pun. Kemudian atasi masalah, temukan pada titik mana itu tidak cocok.
barlop
@barlop Saya tidak punya opsi untuk itu . jadi saya memperbarui dan sekarang semuanya bekerja dengan baik ... Saya tidak benar-benar tahu apa yang harus dilakukan dengan pertanyaan saya sekarang.
UpTide
@ UpTide tidak masalah Anda bisa membiarkannya begitu saja. Ada baiknya Anda menemukan masalah dan penyebab masalah yang Anda miliki.
barlop

Jawaban:

0

Karena Anda menyebutkan penyandian adalah as-ascii, kami dapat menganggap setiap karakter adalah satu byte. Di regex, '.' cocok dengan karakter apa pun, kecuali baris baru, dan Anda ingin setiap bagian individu dari baris baru CR / LF dicocokkan secara terpisah, karena keduanya dua byte.

Saya juga akan membuat asumsi bahwa Anda sedang memproses data teks aktual, dan bukan file biner yang dapat berisi byte di luar pemetaan karakter us-ascii.

Jika semua hal di atas benar, Anda dapat menggunakan regex berikut:

\x0C[^\xFF]{318}

Alasannya '.' tidak berhasil dalam usaha Anda, karena '.' tidak cocok dengan baris baru. Anda juga tidak bisa menggunakan \x0C[.\r\n]{318}, karena '.' wildcard tidak tersedia dalam kelas karakter (grup braket persegi). Nilai Hex FF tidak memetakan ke titik kode apa pun yang valid di dalam rangkaian karakter us-ascii, dan karenanya ketika Anda mencari "karakter apa pun yang bukan karakter FF", Anda akan mengambil byte mempertimbangkan.

Perlu diingat bahwa metode ini menghitung Windows / mac Newlines sebagai dua karakter / byte (sesuai permintaan Anda).

Semoga ini yang kamu cari ...

EDIT - Regex menjelaskan

Ekspresi penuh

\x0C[^\xFF]{318}

Mari kita hancurkan ini.

\ x0C

Ini cocok dengan Single Unicode Grapheme, Anda dapat menemukan informasi lebih lanjut tentang ini disini . Singkatnya, Anda dapat mempertimbangkan \ x versi Unicode dari titik, kecuali itu itu juga bisa cocok dengan jeda baris (ini penting, lebih lanjut tentang ini nanti).

Tapi, karena Anda juga menggunakan ini, saya kira Anda sudah terbiasa dengan hal ini.

[^ \ xFF]

Segala sesuatu di antara [] disebut a Set karakter (jangan bingung dengan konsep yang sama dalam pengkodean Karakter). Anda dapat membaca lebih lanjut tentang itu di Tutorial Regexp, tetapi dalam ringkasan, ini berfungsi sebagai pernyataan "ATAU". [ab] berarti, "a atau b". Ketika ^ digunakan di dalam set karakter, ia berfungsi sebagai negasi. Jadi [^ a] berarti "bukan a". Dalam kasus penggunaan kami, kami mencari karakter apa pun yang bukan nilai HEX FF.

{318}

Dan kami mencari karakter seperti ini, 318 kali. Sintaks {} selalu berlaku untuk elemen Regex tepat di depannya, jadi dalam hal ini set karakter [^ \ xFF].

Kenapa \ xFF?

Dalam notasi heksadesimal, set karakter us-ascii berjalan dari 00 hingga 7E . Nilai apa pun yang lebih tinggi tidak dapat dipetakan ke codepoint us-ascii. Ini berarti bahwa setiap file yang disandikan (dengan benar) di us-ascii, hanya dapat berisi nilai HEX antara 00 dan 7E. Akibatnya, tidak dapat mengandung FF.

Jadi, kita dapat dengan cerdik memanfaatkan ini untuk mencari karakter apa pun termasuk karakter baris baru, karena \ x .. juga mencocokkan baris baru seperti \ x0A dan \ x0C. Ketika kami mencari karakter apa pun itu tidak FF, kami akhirnya menemukan setiap karakter.

Perlu diingat bahwa solusi ini tergantung pada fakta bahwa file Anda dikodekan dalam us-ascii, dan bukan UTF-8.

Wouter
sumber
sementara regex Anda bekerja dengan baik, saya akan sangat menyukai langkah-langkah apa yang dilakukan masing-masing bagiannya. Untuk beberapa alasan saya belum dapat membungkus pikiran saya di sekitar pernyataan regex.
UpTide
ini dia :)
Wouter
Oh dan, itu normal bahwa Anda tidak dapat membungkus pikiran Anda di sekitar pernyataan regex. regex.info/blog/2006-09-15/247 penguasaan regex membutuhkan waktu satu dekade :)
Wouter
Penjelasan Anda luar biasa. Jika saya mengerti ini dengan benar, maka ini menemukan x0C, memilihnya, lalu memilih 318 byte berikutnya (bahkan jika itu adalah x0C). Ini memilih 319 byte, termasuk x0C. Terima kasih! Saya merasa saya perlu membuat lebih banyak akun untuk meningkatkan semangat Anda.
UpTide
Haha, terima kasih :) Dan ya, Anda mengerti ini dengan benar.
Wouter