Tại sao '[az] *' khớp với các chuỗi không theo thứ tự chữ cái?


9

Tôi có một tập tin alphanumvới hai dòng này:

123 abc
this is a line

Tôi bối rối không biết tại sao, khi tôi chạy sed 's/[a-z]*/SUB/' alphanum, tôi nhận được kết quả đầu ra như sau:

SUB123 abc
SUB is a line

Tôi đã mong đợi:

123 SUB
SUB is a line

Tôi đã tìm thấy một bản sửa lỗi (sử dụng sed 's/[a-z][a-z]*/SUB/'thay thế), nhưng tôi không hiểu tại sao nó hoạt động và tôi thì không.

Bạn có thể giúp?



@Kamaraj, cái đó tương tự nhau, nhưng có các mẫu vỏ so với sự nhầm lẫn regexes trên đầu (và câu trả lời tập trung vào cái trước, vì đó là những gì ls foo*sử dụng). Nhưng dù sao đi nữa, nếu bạn tìm thấy những câu hỏi trùng lặp, tôi nghĩ bạn cũng có thể gắn cờ chúng như vậy.
ilkkachu

xem regexr.com để xem hình ảnh trực tiếp & giải thích
RozzA

@RozzA Lưu ý rằng trang web mà bạn liên kết để hỗ trợ các biểu thức chính quy Javascript và Perl, không phải biểu thức thông thường POSIX.
Kusalananda

Câu trả lời:


28

Các mô hình [a-z]*phù hợp với không hoặc nhiều ký tự trong phạm vi ađến z(các thực vật phụ thuộc vào miền địa phương hiện hành). Không có ký tự nào như vậy ở đầu chuỗi 123 abc(tức là mẫu khớp với nhau) và cũng có bốn ký tự ở đầu this is a line.

Nếu bạn cần ít nhất một trận đấu, sau đó sử dụng [a-z][a-z]*hoặc [a-z]\{1,\}, hoặc bật các biểu thức chính quy mở rộng với sed -Evà sử dụng [a-z]+.

Để trực quan hóa nơi mẫu phù hợp, hãy thêm dấu ngoặc đơn xung quanh mỗi trận đấu:

$ sed 's/[a-z]*/(&)/' file
()123 abc
(this) is a line

Hoặc, để xem tất cả các trận đấu trên các dòng:

$ sed 's/[a-z]*/(&)/g' file
()1()2()3() (abc)
(this) (is) (a) (line)

So sánh kết quả cuối cùng với

$ sed -E 's/[a-z]+/(&)/g' file
123 (abc)
(this) (is) (a) (line)

7
Về mặt kỹ thuật [a-z]phù hợp với các yếu tố đối chiếu có thể được tạo thành từ nhiều hơn một ký tự. Chẳng hạn, ở một số địa phương Hungary, [a-z]trận đấu diễn radzs
Stéphane Chazelas

12

Bởi vì *khớp 0 hoặc nhiều lần lặp lại của nguyên tử trước đó và tất cả các công cụ regex cố gắng tìm kết quả khớp đầu tiên. Có một chuỗi con gồm các chữ cái chính xác bằng 0 ở đầu chuỗi của bạn, vì vậy đó là nơi nó khớp. Trong trường hợp chuỗi bắt đầu bằng một chữ cái, các *kết quả khớp càng nhiều càng tốt, nhưng đây là thứ yếu để tìm kết quả khớp ngoài cùng bên trái.

Các trận đấu có độ dài bằng không có thể là một vấn đề nhỏ, và như bạn đã thấy, giải pháp là sửa đổi mẫu sao cho cần ít nhất một ký tự. Với các biểu thức mở rộng, bạn có thể +làm điều đó:sed -E 's/[a-z]+/SUB/'

Để giải trí, hãy thử:

echo 'less than 123 words' | sed 's/[0-9]*/x/g'
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.