Cocok dengan linebreak - \ n atau \ r \ n?

159

Saat menulis jawaban ini , saya harus mencocokkan secara eksklusif pada linebreak alih-alih menggunakan s-flag ( dotall- dot match linebreaks).

Situs yang biasanya digunakan untuk menguji ekspresi reguler berperilaku berbeda ketika mencoba mencocokkan \natau \r\n.

saya perhatikan

  • Regex101 hanya cocok dengan linebreak \n
    ( contoh - hapus \rdan cocok)

  • RegExr cocok dengan linebreak tidak pada \n maupun pada \r\n
    dan saya tidak dapat menemukan sesuatu untuk membuatnya cocok dengan linebreak, kecuali untuk m-flag dan \s
    ( contoh )

  • Debuggex berperilaku lebih berbeda:
    dalam contoh ini hanya cocok menyala \r\n, sementara di
    sini hanya cocok \n, dengan bendera dan mesin yang sama ditentukan

Saya sepenuhnya menyadari m-flag (multiline - ^cocok dengan awal dan $akhir baris), tetapi kadang-kadang ini bukan pilihan. Sama dengan \s, karena cocok dengan tab dan spasi, juga.

Pemikiran saya untuk menggunakan karakter baris baru unicode ( \u0085) tidak berhasil, jadi:

  1. Apakah ada cara yang gagal untuk mengintegrasikan pertandingan pada linebreak (lebih disukai terlepas dari bahasa yang digunakan) ke dalam ekspresi reguler?
  2. Mengapa situs yang disebutkan di atas berperilaku berbeda (terutama Debuggex, hanya cocok sekali \ndan sekali saja \r\n)?
KeyNone
sumber
15
Anda dapat mencoba [\r\n]+- atau sesuatu seperti ini
Iłya Bursov
3
Saya menggunakan: \r?\nuntuk mencocokkan urutan terminasi \r\ndan \ngaris. Ini tidak bekerja untuk \rsintaks Mac lama , tetapi yang cukup langka hari ini.
ridgerunner
6
Hai, saya adalah pendiri debuggex. Ini terlihat seperti bug (untuk debuggex, saya tidak dapat berbicara untuk yang lain). Saya telah menambahkan masalah harga tinggi yang merujuk pertanyaan ini. Kami akan mencapainya sesegera mungkin - saat ini kami memfokuskan semua sumber daya kami (yang sangat terbatas) untuk meluncurkan produk lain.
Sergiu Toarca
2
@ editor untuk menambahkan sintaks Mac untuk itu, Anda bisa melakukan (\ r? \ n | \ r), yang mirip dengan jawaban Peter van der Wal di bawah ini tetapi lebih kompak (10 karakter vs 12 karakter).
Doktor J

Jawaban:

220

Akan menjawab dalam arah yang berlawanan.

2) Untuk penjelasan lengkap tentang \rdan \nsaya harus merujuk ke pertanyaan ini, yang jauh lebih lengkap daripada yang akan saya posting di sini: Perbedaan antara \ n dan \ r?

Singkatnya, Linux menggunakan \nbaris baru, Windows \r\ndan Mac lama \r. Jadi ada beberapa cara untuk menulis baris baru. Alat kedua Anda (RegExr) misalnya cocok dengan tunggal \r.

1) [\r\n]+seperti yang disarankan Ilya akan berhasil, tetapi juga akan cocok dengan beberapa baris baru berturut-turut. (\r\n|\r|\n)lebih benar.

Peter van der Wal
sumber
Jadi, \r/ \nyang tergantung pada sistem operasi - itu hal yang satu mungkin tahu (;)) - tapi kenapa dua debuggex-contoh cocok sekali pada \ r \ n dan sekali pada \ n? Setidaknya tidak ada perbedaan (dalam contoh) yang terlihat bagi saya.
KeyNone
Kemungkinan besar karena Anda menyalin satu dari editor teks windows Anda dan yang lainnya Anda menulis langsung ke teks debuggex. Masing-masing menggunakan jeda baris yang berbeda.
OGHaza
1
Memang, karena dalam contoh ketiga Anda (pria senior ...) ada \r\ndalam teks (jika Anda mengklik kanan dan menunjukkan sumber, Anda akan menemukan {{Infobox XC Championships\r\n|Name =suatu tempat). Alat kedua ditulis dalam Flash dan saat Anda membaca halaman tentang sedikit buggy dengan karakter baris baru.
Peter van der Wal
1
(\r\n|\r|\n)dapat ditulis lebih sederhana sebagai\r\n?
Asad Saeeduddin
2
@ AsadSaeeduddin Tidak, tidak bisa. Itu tidak akan cocok dengan garis akhir Unix\n
Peter van der Wal
12

Anda memiliki akhiran baris yang berbeda dalam teks contoh di Debuggex. Yang sangat menarik adalah bahwa Debuggex tampaknya telah mengidentifikasi gaya akhir baris mana yang Anda gunakan pertama kali, dan Debuggex mengonversi semua akhiran baris tambahan yang dimasukkan ke gaya itu.

Saya menggunakan Notepad ++ untuk menempelkan teks sampel dalam format Unix dan Windows ke dalam Debuggex, dan yang mana yang saya tempelkan dulu adalah sesi yang macet dengan Debuggex.

Jadi, Anda harus mencuci teks melalui editor teks Anda sebelum menempelkannya ke Debuggex. Pastikan Anda menempelkan gaya yang Anda inginkan. Debuggex default ke gaya Unix (\ n).

Juga, NEL (\ u0085) adalah sesuatu yang sepenuhnya berbeda: https://en.wikipedia.org/wiki/Newline#Unicode

(\r?\n)akan mencakup Unix dan Windows. Anda akan membutuhkan sesuatu yang lebih kompleks, seperti (\r\n|\r|\n), jika Anda ingin mencocokkan Mac lama juga.

Dane
sumber
Poin yang sangat menarik tentang debuggex! Juga, terima kasih telah menunjukkan \ u0085, tersesat di sana!
KeyNone
3

Dalam \Rpertandingan PCRE \n, \rdan \r\n.

Paving Cwazy
sumber
Tidak ada pertanyaan
Sandwell
1
@ Sandwell: Maaf, saya tidak mengerti, ini bukan pertanyaan, itu adalah jawaban, lebih sederhana dari(\r\n|\r|\n)
Toto
2

Ini hanya berlaku untuk pertanyaan 1.

Saya memiliki aplikasi yang berjalan di Windows dan menggunakan kotak editor MFC multi-line.
Kotak editor mengharapkan linebreak CRLF, tapi saya perlu menguraikan teks yang dimasukkan
dengan beberapa regex yang benar-benar besar / tidak menyenangkan '.

Saya tidak ingin menekankan hal ini saat menulis regex, jadi
saya akhirnya menormalkan bolak-balik antara parser dan editor sehingga
regex hanya menggunakan\n . Saya juga menjebak operasi tempel dan mengonversinya untuk kotak.

Ini tidak memakan banyak waktu.
Inilah yang saya gunakan.

 boost::regex  CRLFCRtoLF (
     " \\r\\n | \\r(?!\\n) "
     , MODx);

 boost::regex  CRLFCRtoCRLF (
     " \\r\\n?+ | \\n "
     , MODx);


 // Convert (All style) linebreaks to linefeeds 
 // ---------------------------------------
 void ReplaceCRLFCRtoLF( string& strSrc, string& strDest )
 {
    strDest  = boost::regex_replace ( strSrc, CRLFCRtoLF, "\\n" );
 }

 // Convert linefeeds to linebreaks (Windows) 
 // ---------------------------------------
 void ReplaceCRLFCRtoCRLF( string& strSrc, string& strDest )
 {
    strDest  = boost::regex_replace ( strSrc, CRLFCRtoCRLF, "\\r\\n" );
 }

sumber
2

Dengan Python:

# as Peter van der Wal's answer
re.split(r'\r\n|\r|\n', text, flags=re.M) 

atau lebih ketat:

# https://docs.python.org/3/library/stdtypes.html#str.splitlines
str.splitlines()
Keelung
sumber