Kết hợp ngắt dòng - \ n hoặc \ r \ n?


159

Trong khi viết câu trả lời này , tôi phải kết hợp độc quyền trên các ngắt dòng thay vì sử dụng s-flag ( dotall- dấu chấm khớp với ngắt dòng).

Các trang web thường được sử dụng để kiểm tra các biểu thức chính quy hoạt động khác nhau khi cố gắng khớp trên \nhoặc \r\n.

Tôi nhận thấy

  • Regex101 chỉ khớp với các ngắt dòng \n
    ( ví dụ - xóa \rvà nó khớp)

  • RegExr phù hợp với các ngắt dòng không bật \n hoặc không bật \r\n
    và tôi không thể tìm thấy thứ gì đó để khớp với ngắt dòng, ngoại trừ m-flag và \s
    ( ví dụ )

  • Debuggex hành xử thậm chí còn khác hơn:
    trong ví dụ này, nó chỉ khớp với \r\n, trong khi
    ở đây, nó chỉ khớp với \n, với cùng các cờ và công cụ được chỉ định

Tôi hoàn toàn biết về m-flag (multiline - ^khớp với điểm đầu và $điểm cuối của dòng), nhưng đôi khi đây không phải là một lựa chọn. Tương tự \s, vì nó phù hợp với các tab và không gian, quá.

Tôi nghĩ rằng việc sử dụng ký tự dòng mới unicode ( \u0085) không thành công, vì vậy:

  1. Có cách nào không an toàn để tích hợp trận đấu trên một ngắt dòng (tốt nhất là bất kể ngôn ngữ được sử dụng) vào một biểu thức thông thường không?
  2. Tại sao các trang web được đề cập ở trên hoạt động khác nhau (đặc biệt là Debuggex, chỉ khớp một lần duy nhất \nvà một lần duy nhất \r\n)?

15
Bạn có thể thử [\r\n]+- hoặc một cái gì đó như thế này
Iłya Bursov

3
Tôi sử dụng: \r?\nđể phù hợp với cả hai \r\n\ntrình tự kết thúc dòng. Nó không hoạt động với \rcú pháp Mac cũ , nhưng cái đó ngày nay khá hiếm.
Ridgerunner

6
Xin chào, tôi là người sáng lập debuggex. Điều này trông giống như một lỗi (đối với debuggex, tôi không thể nói cho người khác). Tôi đã thêm một vấn đề cao cấp tham khảo câu hỏi này. Chúng tôi sẽ đến với nó càng sớm càng tốt - chúng tôi hiện đang tập trung tất cả các nguồn lực (rất hạn chế) của mình vào việc tung ra một sản phẩm khác.
Sergiu Toarca

2
@ridgerunner để thêm cú pháp của Mac vào đó, bạn có thể làm (\ r? \ n | \ r), tương tự như câu trả lời của Peter van der Wal bên dưới nhưng gọn hơn (10 ký tự so với 12 ký tự).
Doktor J

Câu trả lời:


220

Gonna trả lời theo hướng ngược lại.

2) Để được giải thích đầy đủ về \r\ntôi phải tham khảo câu hỏi này, nó hoàn chỉnh hơn nhiều so với tôi sẽ đăng ở đây: Sự khác biệt giữa \ n và \ r?

Tóm lại, Linux sử dụng \ncho dòng máy mới, Windows \r\nvà máy Mac cũ \r. Vì vậy, có nhiều cách để viết một dòng mới. Công cụ thứ hai của bạn (RegExr) chẳng hạn sẽ khớp trên đĩa đơn \r.

1) [\r\n]+như Ilya đề xuất sẽ hoạt động, nhưng cũng sẽ khớp nhiều dòng mới liên tiếp. (\r\n|\r|\n)đúng hơn


Vì vậy, \r/ \nphụ thuộc vào hệ điều hành - đó là điều người ta có thể biết (;)) - nhưng tại sao hai ví dụ gỡ lỗi lại khớp một lần trên \ r \ n và một lần trên \ n? Ít nhất là không có sự khác biệt (trong các ví dụ) đối với tôi.
KeyNone

Rất có thể là do bạn đã sao chép một trong số các trình soạn thảo văn bản windows của bạn và một cái khác mà bạn đã viết thẳng vào văn bản debuggex. Mỗi dòng sử dụng khác nhau.
OGHaza

1
Thật vậy, bởi vì trong ví dụ thứ ba của bạn (Đàn ông cao cấp ...) có một \r\nvăn bản (nếu bạn nhấp chuột phải và hiển thị nguồn, bạn sẽ tìm thấy {{Infobox XC Championships\r\n|Name =ở đâu đó). Công cụ thứ hai được viết bằng Flash và khi bạn đọc một lỗi nhỏ về trang với các ký tự dòng mới.
Peter van der Wal

1
(\r\n|\r|\n)có thể được viết đơn giản hơn như\r\n?
Asad Saeeduddin

2
@AsadSaeeduddin Không, không thể. Nó sẽ không khớp với dòng kết thúc Unix\n
Peter van der Wal

12

Bạn có các kết thúc dòng khác nhau trong các văn bản ví dụ trong Debuggex. Điều đặc biệt thú vị là Debuggex dường như đã xác định kiểu kết thúc dòng nào bạn đã sử dụng trước tiên và nó chuyển đổi tất cả các kết thúc dòng bổ sung được nhập vào kiểu đó.

Tôi đã sử dụng Notepad ++ để dán văn bản mẫu ở định dạng Unix và Windows vào Debuggex và bất cứ điều gì tôi dán trước là phiên mà Debuggex bị mắc kẹt.

Vì vậy, bạn nên rửa văn bản của mình thông qua trình soạn thảo văn bản trước khi dán nó vào Debuggex. Đảm bảo rằng bạn đang dán kiểu bạn muốn. Debuggex mặc định theo kiểu Unix (\ n).

Ngoài ra, NEL (\ u0085) hoàn toàn khác: https://en.wikipedia.org/wiki/Newline#Unicode

(\r?\n)sẽ bao gồm Unix và Windows. Bạn sẽ cần một cái gì đó phức tạp hơn, như (\r\n|\r|\n), nếu bạn cũng muốn phù hợp với máy Mac cũ.


Điểm rất thú vị về debuggex! Ngoài ra, cảm ơn bạn đã chỉ ra \ u0085, đã đánh lừa ở đó!
KeyNone

3

Trong các \Rtrận đấu PCRE \n, \r\r\n.


Không có câu hỏi
Sandwell

1
@Sandwell: Xin lỗi, tôi không hiểu bạn, đây không phải là một câu hỏi, nó là một câu trả lời, đơn giản hơn(\r\n|\r|\n)
Toto

2

Điều này chỉ áp dụng cho câu hỏi 1.

Tôi có một ứng dụng chạy trên Windows và sử dụng hộp soạn thảo MFC nhiều dòng.
Hộp soạn thảo mong đợi các ngắt dòng CRLF, nhưng tôi cần phân tích văn bản được nhập
bằng một số biểu thức chính thực sự lớn / khó chịu '.

Tôi không muốn nhấn mạnh về điều này trong khi viết regex, vì vậy
cuối cùng tôi đã bình thường hóa qua lại giữa trình phân tích cú pháp và trình soạn thảo để
regexs chỉ sử dụng \n. Tôi cũng bẫy hoạt động dán và chuyển đổi chúng cho các hộp.

Điều này không mất nhiều thời gian.
Đây là những gì tôi sử dụng.

 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

Trong Python:

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

hoặc nghiêm ngặt hơn:

# https://docs.python.org/3/library/stdtypes.html#str.splitlines
str.splitlines()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.