2009-09-03 42 views
14

Regex sau tìm văn bản giữa các bản chất FTW và ODP.Regex: (?! ...) có nghĩa là gì?

/FTW(((?!FTW|ODP).)+)ODP+/ 

(?! ... ) làm gì?

+0

Đây là perl cụ thể (và PCRE), là nó không? – tylerl

+1

@tylerl: Nó áp dụng cho bất kỳ hương vị nào hỗ trợ lookahead: Perl, Python, PHP, .NET, Java, JavaScript, JGSoft, et al. –

Trả lời

22

(?!regex)zero-width negative lookahead. Nó sẽ kiểm tra các ký tự tại vị trí con trỏ hiện tại và tiến lên, thử nghiệm rằng chúng thực hiện NOT khớp với regex được cung cấp và sau đó trả lại con trỏ về vị trí bắt đầu.

Toàn bộ regexp:

/ 
FTW   # Match Characters 'FTW' 
(   # Start Match Group 1 
    (   # Start Match Group 2 
    (?!FTW|ODP) # Ensure next characters are NOT 'FTW' or 'ODP', without matching 
    .    # Match one character 
)+   # End Match Group 2, Match One or More times 
)    # End Match Group 1 
OD   # Match characters 'OD' 
P+   # Match 'P' One or More times 
/

Vì vậy, - Hunt cho FTW, sau đó chụp trong khi tìm kiếm ODP+ để chấm dứt chuỗi của chúng tôi. Cũng đảm bảo rằng dữ liệu giữa FTWODP+ không chứa FTW hoặc ODP

+1

+1 để giải thích chính xác cách nó được sử dụng trong regex được cung cấp. –

7

Có nghĩa là "không theo sau ...". Về mặt kỹ thuật, đây là những gì được gọi là negative lookahead trong đó bạn có thể nhìn vào những gì phía trước trong chuỗi mà không cần chụp. Nó là một lớp xác nhận chiều rộng bằng 0, có nghĩa là các biểu thức như vậy không nắm bắt bất kỳ phần nào của biểu thức.

18

Từ perldoc:

Một zero-width tiêu cực nhìn về phía trước khẳng định. Ví dụ: /foo(?!bar)/ khớp với mọi lần xuất hiện của "foo" không được theo sau bởi "bar". Tuy nhiên, lưu ý rằng nhìn về phía trước và phía sau không giống nhau. Bạn không thể sử dụng cái này cho cái nhìn phía sau.

Nếu bạn đang tìm kiếm "thanh" không có trước "foo", /(?!foo)bar/ sẽ không làm những gì bạn muốn. Đó là bởi vì (?!foo) chỉ nói rằng điều tiếp theo không thể là "foo" - và nó không phải, đó là "thanh", vì vậy "foobar" sẽ khớp. Bạn sẽ phải làm một cái gì đó như /(?!foo)...bar/ cho điều đó. Chúng tôi nói "thích" vì có trường hợp "bar" của bạn không có ba ký tự trước đó. Bạn có thể bao gồm theo cách này: /(?:(?!foo)...|^.{0,2})bar/. Đôi khi nó vẫn còn dễ dàng hơn chỉ để nói:

if (/bar/ && $` !~ /foo$/) 
+0

Để xem xét tiêu cực, nếu trình phân tích cú pháp hỗ trợ nó, bạn chỉ có thể sử dụng '(? Amber

+0

"Google là bạn của bạn" nếu bạn có một số ý tưởng về các thuật ngữ tìm kiếm để sử dụng. Dù sao, bạn không có ý định liên kết đến đoạn này? http://perldoc.perl.org/perlre.html#Look-Around-Assertions –

+0

trong trường hợp này tôi nghĩ rằng nó khá dễ dàng để biết đến google cho tài liệu regex. có, nhờ chỉnh sửa liên kết – mkoryak

0

'?!' thực sự là một phần của '(?! ...)', điều đó có nghĩa là bất kỳ cái gì bên trong đều KHÔNG khớp ở vị trí đó.

3

Lập trình viên phải nhập quá nhanh. Một số nhân vật trong mẫu đã bị lật. Sửa chữa:

/WTF(((?!WTF|ODP).)+)ODP+/ 
+2

Haters: Thôi nào, làm sáng lên một chút. Đó là một trò đùa đảo chữ poking tại một số người khinh bỉ Regex. Mặc dù không phải là "hữu ích", chúng ta không có nó quá ngột ngạt ở đây. – brianreavis

+0

+1 để chống lại sự căm ghét. – nilamo

+1

Các câu trả lời của Jokey có khả năng gợi ra các downvotes ngay cả khi chúng * hữu ích; đó là cách nó ở đây. Mất một chút làm quen với, nhưng tôi nghĩ rằng nó có giá trị nó, về chất lượng trang web tổng thể. –

2

Regex

/FTW(((?!FTW|ODP).)+)ODP+/ 

trận đấu đầu tiên FTW ngay lập tức sau đó không phải bởi FTW cũng không bởi ODP, sau đó tất cả các ký tự theo dõi để ODP đầu tiên (nhưng nếu có FTW là ở đâu đó trong họ sẽ có không phù hợp) thì tất cả các chữ cái P theo sau.

Vì vậy, trong chuỗi:

FTWFTWODPFTWjjFTWjjODPPPPjjODPPPjjj

nó sẽ phù hợp với phần in đậm

FTWFTWODPFTWjj FTWjjODPPPP jjODPPPjjj

+0

Lỗi nhẹ trong logic của bạn ở đó, Vì xác nhận lookahead nằm bên trong nhóm kết hợp của '+' ', nó khớp với bất kỳ văn bản nào giữa FTW .... ODP không có con chip hoặc FTW hoặc ODP bên trong nó. – gnarf

+0

@gnarf là ​​đúng: tham lam hay không, regex này sẽ không bao giờ phù hợp với nhiều hơn một sự xuất hiện của "FTW" hoặc "ODP". –

+0

Bạn đúng, sai lầm của tôi. Tôi đang sửa lỗi này để tránh nhầm lẫn giữa người xem trong tương lai. –