2010-07-10 26 views
22

Tôi chắc chắn điều này đã được yêu cầu trước đó, nhưng tôi không thể tìm thấy nó. Về cơ bản, giả sử bạn đang phân tích cú pháp một tệp văn bản có nguồn gốc không xác định và muốn thay thế ngắt dòng bằng một số dấu phân cách khác, đây có phải là regex hay nhất hay không?Regex nền tảng chéo để loại bỏ ngắt dòng là gì?

(\r\n)|(\n)|(\r)

+1

bạn có quan tâm đến ngắt dòng-Mac kiểu cũ ('\ r'), hoặc chỉ về Unix và Windows (' \ n' và '\ r \ n')? –

+1

có thể trùng lặp của [Cụm từ thông dụng để khớp với các ký tự dòng mới trên nền tảng chéo] (http://stackoverflow.com/questions/1331815/regular-expression-to-match-cross-platform-newline-characters) – Amarghosh

Trả lời

0

Chỉ cần thay thế /[\r\n]+/g với một chuỗi rỗng "".

Nó sẽ thay thế tất cả \r\n bất kể thứ tự xuất hiện trong chuỗi.

+0

Điều này sẽ thay thế bất kỳ số nào ngắt dòng với một mã thông báo thay thế. –

+0

@Andreas Anh ấy muốn xóa ngắt dòng. – Amarghosh

+1

Vâng, anh ấy muốn thay thế chúng bằng một dấu tách khác ... –

20

Hãy kiểm tra xem động cơ regex của bạn có hỗ trợ \R làm lớp ký tự viết tắt và bạn sẽ không cần phải quan tâm đến các combo khác nhau của newline/linefeed Unicode. Nếu được triển khai chính xác, sau đó bạn có thể đối sánh tất cả các kết thúc dòng ascii hoặc Unicode khác nhau một cách rõ ràng bằng cách sử dụng \R.

Trong Unicode, bạn cần phát hiện NEL (Dòng kết thúc OS/390, \ x85) LS (Bộ tách dòng, \ x2028) và PS (Tách đoạn, \ x2029) nếu bạn muốn hoàn toàn nền tảng trong những ngày này.

Có thể gây tranh cãi cho dù LS, NEL và PS có được coi là ngắt dòng, kết thúc dòng hay không gian màu trắng. Tiêu chuẩn XML 1.0, ví dụ: does not recognize NEL là ký tự ngắt dòng. ECMAScript xử lý LSPS làm ngắt dòng nhưng NEL làm khoảng trắng. Perl unicode regexs sẽ đối xử với VT, FF, CR, CRLF, NEL, LSPS như ngắt dòng với mục đích ^$ ký tự meta regex.

Các Unicode Implementation Guide (mục 5.8 và bảng 5.3) có lẽ là đặt cược tốt nhất về việc xử lý dứt khoát của "đường kẻ mới" là gì.

Nếu bạn chỉ quan tâm đến ascii với các biến thể cổ điển DOS/Windows/Unix/Mac, regex tương đương với \R(?>\r\n|[\r\n])

Trong Unicode, tương đương với \R(?>\r\n|\n|\x0b|\f|\r|\x85|\x2028|\x2029) Các \x0b trong đó là một dọc chuyển hướng; một lần nữa, điều này có thể hoặc có thể không phù hợp với bạn định nghĩa về những gì một ngắt dòng là, nhưng điều đó không phù hợp với khuyến nghị của Unicode Implantation. (FF hoặc \x0C không được bao gồm trong regex vì Nguồn cấp dữ liệu là trang mới, không phải là dòng mới trong định nghĩa.)

+0

"utf8" trong câu trả lời của bạn phải là "Unicode". UTF-8 chỉ là một trong các mã hóa ký tự Unicode. –

+0

Bạn nói đúng, nhưng các tài liệu tôi đang đề cập đến (hướng dẫn PCRE) có cùng vấn đề! Edit made ... – dawg

+2

Trong Java, phần '\ x2028 | \ x2029' phải được viết '\ u2028 | \ u2029', vì' \ xhh' chỉ được sử dụng cho các giá trị ký tự hex gồm 2 chữ số, trong khi '\ uhhhh' được sử dụng cho các giá trị ký tự hex gồm 4 chữ số. –

2

Regex để tìm bất kỳ đầu cuối dòng Unicode nào phải là (?>\x0D\x0A?|[\x0A-\x0C\x85\x{2028}\x{2029}]) thay vì so với drewk đã viết nó, ít nhất là trong Perl. Lấy trực tiếp từ tài liệu perl 5.10.0 (nó đã được gỡ bỏ trong các phiên bản sau này). Lưu ý các dấu ngoặc sau \x: U + 2029 là \x{2029} nhưng \x2029 là một khoảng trắng ASCII (U + 0020) + một chữ số 2 + a chữ số 9. \n bên ngoài một lớp nhân vật, cũng không được bảo đảm để phù hợp với \x{0a}.

1

Nếu nền tảng của bạn không hỗ trợ lớp học \R như được đề xuất bởi @dawg ở trên, bạn vẫn có thể tạo một giải pháp khá thanh lịch và mạnh mẽ nếu nền tảng của bạn hỗ trợ phép trừ tiêu cực lookaround hoặc lớp nhân vật (ví dụ: trừ lớp Java thông qua syntax[x&&[^y]]).

Trong hầu hết các ngữ pháp diễn đạt thông thường, ký tự dấu chấm được định nghĩa là "bất kỳ ký tự nào ngoại trừ ký tự dòng mới" (xem ví dụ, đối với JavaScript, here). Nếu bạn khớp một thứ gì đó với các đặc điểm sau:

  1. không (bất kỳ ký tự nào ngoại trừ ký tự dòng mới) → ký tự dòng mới; và
  2. là khoảng trắng

Vì tôi hiện đang làm việc trong JavaScript, mà AFAIK không có \R viết tắt hoặc nhân vật lớp trừ, tôi vẫn có thể sử dụng lookahead tiêu cực để có được những gì tôi muốn. Các biểu hiện thường xuyên sau phù hợp với tất cả các dòng mới:

/((?!.)\s)+/g 

Và mã JavaScript sau, ít nhất là khi chạy trong Chrome 42.0.2311.90m trên Windows 7, làm mất tất cả các loại newlines rằng JavaScript (tức là "ECMAScript" đề cập trong đoạn thứ ba @ Dawg của) công nhận:

var input = "hello\r\n\f\v\u2028\u2029 world"; 
 
var output = input.replace(/((?!.)\s)+/g, ""); 
 
document.write(output); // hello world

Các vấn đề liên quan