regex để khớp với EOF


90

Tôi có một số dữ liệu giống như thế này

john, dave, chris
rick, sam, bob
joe, milt, paul

Tôi đang sử dụng regex này để khớp tên

/(\w.+?)(\r\n|\n|,)/

mà làm việc cho hầu hết các phần nhưng các tập tin đầu đột ngột sau khi từ cuối cùng có nghĩa là giá trị cuối cùng không kết thúc trong \r\n, \nhoặc ,nó kết thúc với EOF. Có cách nào để đối sánh EOF trong regex để tôi có thể đặt nó ngay trong nhóm thứ hai đó không?


Bạn đang cố gắng chụp tất cả các tên trong một nhóm hoặc một nhóm chụp cho mỗi tên?
Andrew Hare

một điều cần làm khi gặp sự cố với regex là thử tách biệt các phần tử của bạn theo mẫu. nếu bạn lo lắng về mã thông báo ở cuối, hãy kiểm tra biểu thức của bạn mà không có nó.
akf

chỉ muốn thêm một trang web lớn thử nghiệm regex: regexplanet.com/simple
northpole


@Sinan - Tôi đồng ý; hợp nhất
Marc Gravell

Câu trả lời:


160

Tôi \Zđã mất một lúc để tìm ra câu trả lời cho câu hỏi này , nhưng nó đã hoạt động ngay bây giờ. Lưu ý rằng ngược lại, \Akhớp với phần đầu của toàn chuỗi (trái ngược với ^$khớp với phần đầu của một dòng).


5
Chỉ cần lưu ý nếu bạn đang theo đuổi tính năng như vậy trong netbeans để tìm kiếm tệp dự án trái ngược với tìm kiếm trong tệp , phần sau sẽ hoạt động khác ... (\s*)\?>(\s*)\Z... và sau khi tìm hiểu thêm, đây là những gì sẽ hoạt động trên thư mục dự án : (\s*)\?>(\s*)(\n*)(\W)\Z FYI: cái này để thay thế tất cả các thẻ php đóng bằng cách ngắt dòng ở cuối tệp.
MediaVince

1
Hóa ra \Acũng hoạt động trong Visual Studio tìm và thay thế. Như luôn luôn sử dụng những thứ như vậy một cách thận trọng nhưng nó giúp tôi tiết kiệm được rất nhiều thao tác thủ công khi tôi cảm thấy vui vẻ thì nó sẽ thực sự làm đúng.
Steve Pettifer

Trong khi tôi đang sử dụng Scannerlớp của Java để đọc toàn bộ tệp cùng một lúc; nếu tôi sử dụng \Zlàm dấu phân cách, ký tự dòng mới ở cuối sẽ được cắt bớt. Khi tôi thay đổi dấu phân cách thành \z, ký tự dòng mới ở cuối được giữ nguyên. Có vẻ như câu trả lời của Martin Dorey cũng áp dụng cho Java.
mmdemirbas

24

EOF thực sự không phải là một ký tự. Nếu bạn có một chuỗi nhiều dòng, thì '$' sẽ khớp với phần cuối của chuỗi cũng như phần cuối của một dòng.

Trong Perl và những người anh em của nó, \A\Zđối sánh phần đầu và phần cuối của chuỗi, hoàn toàn bỏ qua dấu ngắt dòng.

Các phần mở rộng GNU cho các regex POSIX sử dụng \`\'cho những điều tương tự.


17

Trong Visual Studio, bạn có thể tìm EOF thích vậy: $(?![\r\n]). Điều này hoạt động cho dù kết thúc dòng của bạn là CR, CRLF hay chỉ LF.

Như một phần thưởng, bạn có thể đảm bảo tất cả các tệp mã của mình có điểm đánh dấu dòng mới cuối cùng như sau:

               Find What: (?<![\r\n])$(?![\r\n])
            Replace With: \r\n
 Use Regular Expressions: checked
Look at these file types: *.cs, *.cshtml, *.js

Cách thức hoạt động:

Tìm bất kỳ đầu dòng nào (đối sánh độ rộng bằng 0) không đứng trước CR hoặc LF và cũng không theo sau CR hoặc LF. Một số suy nghĩ sẽ cho bạn thấy tại sao nó hoạt động!

Lưu ý rằng bạn nên Thay thế bằng ký tự kết thúc dòng mong muốn của mình, có thể là CR, LF hoặc CRLF.


Có một lỗi trong Visual Studio 2019 khi thực hiện thay thế tất cả bằng điều này có thể dẫn đến hai dòng mới được thêm vào cuối tệp. Tôi nghĩ rằng nó có liên quan đến tùy chọn tự động chèn dòng mới khi lưu.
Stevoisiak

9

Đối chiếu hành vi của \ Z được đề xuất của Ryan với \ z:

$ perl -we 'my $ corpus = "xin chào \ n"; $ corpus = ~ s / \ Z / world / g; print (": $ corpus: \ n") '
:Chào thế giới
thế giới:
$ perl -we 'my $ corpus = "xin chào \ n"; $ corpus = ~ s / \ z / world / g; print (": $ corpus: \ n") '
:xin chào
thế giới:
$ 

perlre sez:

\ Z Chỉ khớp ở cuối chuỗi hoặc trước dòng mới ở cuối
\ z Chỉ khớp ở cuối chuỗi

Bản dịch của test case sang Ruby (1.8.7, 1.9.2) cũng hoạt động như vậy.


2

Bạn có thực sự phải chụp các dải phân cách? Nếu không, regex này sẽ là tất cả những gì bạn cần:

/\w+/

Điều đó giả sử rằng tất cả các chuỗi con bạn muốn khớp hoàn toàn bao gồm các ký tự từ, như trong ví dụ của bạn.



2

Gần đây tôi đã tìm kiếm một thứ như thế này, nhưng dành cho JavaScript.

Đặt vấn đề này ở đây để bất kỳ ai có cùng vấn đề đều có thể hưởng lợi

var matchEndOfInput = /$(?![\r\n])/gm;

Về cơ bản, điều này sẽ khớp với phần cuối của dòng, không được theo sau bởi ký tự xuống dòng hoặc ký tự dòng mới. Về bản chất, điều này giống như \Znhưng đối với JavaScript.


1

Giả sử bạn đang sử dụng công cụ sửa đổi thích hợp buộc xử lý toàn bộ chuỗi (không phải từng dòng - và nếu \ n phù hợp với bạn, bạn đang sử dụng nó), chỉ cần thêm một thay thế khác - cuối chuỗi: (\ r \ n | \ n |, | $)


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.