เทียบ linebreaks - \ n หรือ \ r \ n?


159

ในขณะที่เขียนคำตอบนี้ฉันต้องจับคู่เฉพาะกับการกระจายบรรทัดแทนการใช้s-flag ( dotall- จุดจับคู่การกระจายบรรทัด)

เว็บไซต์ที่มักจะใช้ในการทดสอบการแสดงออกปกติทำงานแตกต่างกันเมื่อพยายามที่จะจับคู่หรือ\n\r\n

ฉันสังเกตเห็น

  • Regex101 จับคู่ linebreaks เฉพาะใน\n
    ( ตัวอย่าง - ลบ\rและตรงกับ)

  • RegExr จับคู่ linebreaks ไม่ว่าบน\n หรือบน\r\n
    และฉันไม่พบสิ่งที่จะทำให้ตรงกับ linebreak ยกเว้นm-flag และ\s
    ( ตัวอย่าง )

  • Debuggex มีพฤติกรรมที่แตกต่างกันมากขึ้น:
    ในตัวอย่างนี้ตรงกับเฉพาะใน\r\nขณะ
    ที่ตรงนี้เท่านั้นที่ตรง\nกับด้วยธงและเครื่องยนต์เดียวกันที่ระบุ

ฉันตระหนักถึงm-flag (หลายบรรทัด- ทำให้^ตรงกับจุดเริ่มต้นและ$จุดสิ้นสุดของบรรทัด) แต่บางครั้งนี่ไม่ใช่ตัวเลือก เช่นเดียวกับ\sตรงกับแท็บและช่องว่างเช่นกัน

ความคิดของฉันในการใช้อักขระขึ้นบรรทัดใหม่ของ Unicode ( \u0085) ไม่ประสบความสำเร็จดังนั้น:

  1. มีวิธีที่ไม่ปลอดภัยหรือไม่ที่จะรวมการแข่งขันใน linebreak (โดยเฉพาะอย่างยิ่งโดยไม่คำนึงถึงภาษาที่ใช้) ในการแสดงออกปกติ?
  2. เหตุใดเว็บไซต์ที่กล่าวถึงข้างต้นจึงมีพฤติกรรมแตกต่างกัน (โดยเฉพาะ Debuggex การจับคู่ครั้งเดียว\nและครั้งเดียวเท่านั้น\r\n)

15
คุณสามารถลอง[\r\n]+- หรืออะไรทำนองนี้
Iłya Bursov

3
ฉันใช้: \r?\nเพื่อจับคู่ทั้งสอง\r\nและ\nลำดับการยกเลิกบรรทัด มันใช้ไม่ได้กับ\rไวยากรณ์ Mac เก่าแต่อันนี้หายากทีเดียวในทุกวันนี้
ridgerunner

6
เฮ้ฉันเป็นผู้ก่อตั้ง debuggex ดูเหมือนว่าเป็นข้อบกพร่อง (สำหรับ debuggex ฉันไม่สามารถพูดกับคนอื่นได้) ฉันได้เพิ่มปัญหาระดับสูงที่อ้างอิงคำถามนี้ เราจะไปให้เร็วที่สุด - ขณะนี้เรามุ่งเน้นทรัพยากร (จำกัด มาก) ทั้งหมดของเราในการเปิดตัวผลิตภัณฑ์อื่น
Sergiu Toarca

2
@ridgerunner เพื่อเพิ่มไวยากรณ์ของ Mac คุณสามารถทำ (\ r? \ n | \ r) ซึ่งคล้ายกับคำตอบของ Peter van der Wal ด้านล่าง แต่กะทัดรัดกว่า (10 ตัวอักษรเทียบกับ 12 ตัวอักษร)
Doktor J

คำตอบ:


220

จะตอบในทิศทางตรงกันข้าม

2) สำหรับคำอธิบายที่สมบูรณ์เกี่ยวกับ\rและ\nฉันต้องอ้างถึงคำถามนี้ซึ่งสมบูรณ์กว่าที่ฉันจะโพสต์ที่นี่: ความแตกต่างระหว่าง \ n และ \ r?

เรื่องยาวสั้น Linux ใช้\nสำหรับสายใหม่, Windows \r\nและ \rMac ดังนั้นจึงมีหลายวิธีในการเขียนขึ้นบรรทัดใหม่ เครื่องมือที่สองของคุณ (RegExr) \rไม่เช่นการจับคู่อยู่คนเดียว

1) [\r\n]+ตามที่ Ilya แนะนำจะใช้งานได้ แต่จะจับคู่บรรทัดใหม่ต่อเนื่องหลายบรรทัด (\r\n|\r|\n)ถูกต้องมากขึ้น


ดังนั้น\r/ \nขึ้นอยู่กับระบบปฏิบัติการ - นั่นเป็นสิ่งที่เราอาจรู้ (;)) - แต่ทำไมทั้งสองตัวอย่าง debuggex ตรงกับครั้งเดียวใน \ r \ n และอีกครั้งใน \ n? อย่างน้อยก็ไม่มีความแตกต่าง (ในตัวอย่าง) สำหรับฉัน
KeyNone

เป็นไปได้มากว่าคุณคัดลอกตัวแก้ไขข้อความใน windows และอีกอันที่คุณเขียนลงไปใน debuggex textarea แต่ละตัวใช้การแบ่งบรรทัดที่แตกต่างกัน
OGHaza

1
แน่นอนเพราะในตัวอย่างที่สามของคุณ (ชายอาวุโส ... ) มี\r\nข้อความอยู่ (ถ้าคุณคลิกขวาและแสดงแหล่งที่มาคุณจะพบ{{Infobox XC Championships\r\n|Name =บางแห่ง) เครื่องมือที่สองเขียนขึ้นใน Flash และเมื่อคุณอ่านข้อมูลในหน้าเพจด้วยบิตของอักขระขึ้นบรรทัดใหม่
Peter van der Wal

1
(\r\n|\r|\n)สามารถเขียนได้ง่ายขึ้นเช่น\r\n?
ซาด Saeeduddin

2
@ AsadSaeeduddin ไม่สามารถทำได้ มันจะไม่ตรงกับตอนจบของ Unix\n
Peter van der Wal

12

คุณมีการลงท้ายบรรทัดที่แตกต่างกันในข้อความตัวอย่างใน Debuggex สิ่งที่น่าสนใจเป็นพิเศษคือ Debuggex ดูเหมือนจะระบุสไตล์การสิ้นสุดบรรทัดที่คุณใช้ก่อนและจะแปลงการสิ้นสุดบรรทัดเพิ่มเติมทั้งหมดที่ป้อนให้กับสไตล์นั้น

ฉันใช้ Notepad ++ เพื่อวางข้อความตัวอย่างในรูปแบบ Unix และ Windows ลงใน Debuggex และสิ่งใดก็ตามที่ฉันวางไว้ก่อนนั้นคือเซสชันใดของ Debuggex ที่ติดอยู่

ดังนั้นคุณควรล้างข้อความของคุณผ่านเครื่องมือแก้ไขข้อความก่อนวางลงใน Debuggex ตรวจสอบให้แน่ใจว่าคุณกำลังวางสไตล์ที่คุณต้องการ Debuggex ใช้ค่าเริ่มต้นเป็นสไตล์ Unix (\ n)

นอกจากนี้ NEL (\ u0085) เป็นสิ่งที่แตกต่างอย่างสิ้นเชิง: https://en.wikipedia.org/wiki/Newline#Unicode

(\r?\n)จะครอบคลุม Unix และ Windows คุณจะต้องมีสิ่งที่ซับซ้อนกว่าเช่น(\r\n|\r|\n)ถ้าคุณต้องการจับคู่ Mac เครื่องเก่าเช่นกัน


ประเด็นที่น่าสนใจมากเกี่ยวกับ debuggex! นอกจากนี้ขอบคุณที่ชี้ให้เห็น \ u0085 เข้าใจผิดที่นั่น!
KeyNone


2

ใช้กับคำถามที่ 1 เท่านั้น

ฉันมีแอพที่ทำงานบน Windows และใช้กล่องตัวแก้ไข MFC หลายบรรทัด
กล่องเครื่องมือแก้ไขคาดว่าจะมีการแพร่กระจาย CRLF แต่ฉันต้องแยกวิเคราะห์ข้อความที่ป้อน
ด้วยใหญ่และน่ารังเกียจจริงๆ

ฉันไม่ต้องการเครียดเกี่ยวกับเรื่องนี้ในขณะที่เขียน regex ดังนั้น
ฉันจึงสิ้นสุดการทำ normalizing ไปมาระหว่าง parser และ editor เพื่อให้
regex ใช้\nเพียงแค่การใช้งาน ฉันยังดักการปฏิบัติการแปะและแปลงเป็นกล่อง

ใช้เวลาไม่นาน
นี่คือสิ่งที่ฉันใช้

 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" );
 }

2

ใน Python:

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

หรือเข้มงวดมากขึ้น:

# https://docs.python.org/3/library/stdtypes.html#str.splitlines
str.splitlines()
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.