2009-05-28 42 views
16

Tôi thường quên các công cụ sửa đổi biểu thức chính quy ms và sự khác biệt của chúng. Một cách hay để ghi nhớ chúng là gì?Sự khác biệt giữa các công cụ sửa đổi biểu thức chính quy 'm' và 's'?

Như tôi hiểu họ, đó là:

'm' là dành cho nhiều dòng, do đó ^$ sẽ phù hợp với đầu chuỗi và kết thúc của chuỗi nhiều lần. (Như chia bởi \n)

's' là để chấm sẽ phù hợp thậm chí kí tự xuống dòng

Thông thường, tôi chỉ sử dụng

/some_pattern/ism 

Nhưng nó có lẽ là tốt hơn để sử dụng chúng cho phù hợp (thường là "s" trong trường hợp của tôi).

Bạn nghĩ điều gì có thể là một cách hay để ghi nhớ chúng, thay vì quên thứ nào là thời gian nào?

Trả lời

16

Không phải là hiếm khi tìm thấy ai đó đang sử dụng regex trong nhiều năm mà vẫn không hiểu cách hai công cụ sửa đổi này hoạt động như thế nào. Như bạn đã quan sát, tên "đa dòng" và "singleline" không phải là rất hữu ích. Họ có vẻ như họ phải loại trừ lẫn nhau, nhưng họ hoàn toàn độc lập. Tôi đề nghị bạn bỏ qua tên và tập trung vào những gì họ làm: m thay đổi hành vi của các neo (^$) và s thay đổi hành vi của dấu chấm (.).

Một người nổi bật trộn lẫn các chế độ là tác giả của Ruby. Ông đã tạo ra triển khai regex của riêng mình dựa trên Perl's, ngoại trừ việc ông quyết định có ^$ luôn là đường neo - tức là chế độ nhiều dòng luôn bật. Thật không may, anh ta cũng đã đặt tên không chính xác chế độ chấm-khớp-mọi thứ nhiều dòng. Vì vậy, Ruby không có công cụ sửa đổi s, nhưng công cụ sửa đổi m của nó sẽ làm những gì mà các hương vị khác có được là s.

Vì luôn sử dụng /ism, tôi khuyên bạn nên chống lại nó. Nó hầu như vô hại, như bạn đã phát hiện ra, nhưng nó sẽ gửi một thông điệp khó hiểu cho bất cứ ai khác đang cố gắng tìm ra những gì mà regex phải làm (hoặc thậm chí cho chính bạn, trong tương lai).

+0

điều gì sẽ xảy ra nếu trong Ruby, tôi muốn nó chỉ khớp bắt đầu và kết thúc của chuỗi, bỏ qua \ n? –

+1

Sau đó, bạn sử dụng \ A và \ z. Những người có sẵn trong hầu hết các hương vị khác, quá; bạn chỉ không thấy chúng được sử dụng rất nhiều. –

10

Tôi thích giải thích trong 'người đàn ông perlre':

m Treat chuỗi như m dòng ultiple.
s Chuỗi xử lý là s dòng ingle.

Với nhiều dòng,^và $ áp dụng cho các dòng riêng lẻ (tức là trước và sau dòng mới).
Với một dòng,^và $ áp dụng cho toàn bộ, và \ n chỉ trở thành một ký tự khác mà bạn có thể khớp.

[Sai] Bằng cách sử dụng cả hai m và s như bạn đã mô tả, tôi mong đợi thứ hai sẽ được ưu tiên, vì vậy bạn sẽ luôn ở chế độ nhiều dòng với/ism. [/ sai]

Tôi đã không đọc đủ xa:
Các "/ s" và "/ m" bổ cả ghi đè lên các thiết lập $ *. Tức là, không có vấn đề gì $ * chứa, "/ s" không có "/ m" sẽ buộc "^" chỉ khớp ở đầu chuỗi và "$" để chỉ khớp ở cuối (hoặc ngay trước một dòng mới tại kết thúc) của chuỗi. Cùng với nhau, như/ms, chúng cho phép "." phù hợp với bất kỳ ký tự nào, trong khi vẫn cho phép "^" và "$" đối sánh, tương ứng, ngay sau và ngay trước dòng mới trong chuỗi.

+0

hm ... có đúng là nếu chúng ta không sử dụng 'm' hoặc 's', thì nó không phải là nhiều dòng hay một dòng đơn? bạn sẽ nghĩ nó phải là một. –

+0

bằng cách này, cách này mô tả nó sẽ làm cho nó một cuộc xung đột cho^và $ nếu chúng ta sử dụng cả hai 'm' và 's' ... tôi đang sử dụng def từ PHP ... vì vậy có lẽ def là một hơi khác trên nền tảng khác. –

1

có lẽ cách này, tôi sẽ không bao giờ quên:

khi tôi muốn để phù hợp trên đường, tôi sẽ tự nhiên nghĩ (thường sử dụng * để phù hợp với cái gì đó không quan trọng nếu nó trải rộng trên nhiều dòng.?) của multiline, và do đó, 'm'. Vâng, 'm' thực sự không phải là một, vì vậy nó là 's'.

(kể từ khi tôi đã nhớ 'ism' rất tốt ... vì vậy tôi luôn có thể nhớ nó không phải là 'm', sau đó nó phải là 's').

nỗ lực què khác bao gồm:

s là dành cho DOTALL, nó là dành cho DOT để phù hợp với tất cả.
m là nhiều dòng - dành cho ^$ để khớp với nhiều lần.

+3

s là cho "siêu trận đấu", vì vậy bạn thậm chí có thể phù hợp với các nhân vật vô hình;) – JimG

+0

@JimG đó là một trong những điều hài hước nhất mà tôi từng đọc trên stackoverflow –

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