2013-06-01 30 views
13

Trong một mã nguồn tôi thấy regex này:Điều gì khớp với regex này: qr/(?!) /;

qr/(?!)/; 

Tôi chỉ đơn giản là không thể tìm ra những gì này phù hợp.

Thành thật mà nói, tuyệt đối không hiểu ý nghĩa của số Xác nhận xem trước âm tính không có chiều rộng bằng không. - những gì tôi tìm thấy trong perlre. :(

Ai đó có thể giải thích nó trong một ngôn ngữ loài người, xin vui lòng? :)

Trả lời

14

Điều này là hợp pháp nhưng không có gì cả.

Cấu trúc (?!...)xác nhận xem xét tiêu cực. Cụ thể, điều này có nghĩa là: "khớp vị trí mà regex theo sau (...) nên không phải khớp với chuỗi đầu vào".

Nhưng trong trường hợp này, "regex theo sau" là regex trống, phù hợp với mọi thứ. Vì vậy, điều này về cơ bản regex nói "phù hợp với một vị trí mà những gì sau đây không thể được xuất hiện bởi các regex rỗng" ... Và có thể không có vị trí như vậy, bất kể chuỗi đầu vào. Đây là một cấu trúc regex luôn thất bại!

+0

Không muốn nói dối - vì vậy không thể nói: Ahh, hoàn toàn hiểu ngay bây giờ. Nhưng, lời giải thích của bạn cho tôi một chút ánh sáng vào bóng tối. Cảm ơn bạn. :) Chấp nhận. – novacik

+0

Tôi có thể cung cấp thêm chi tiết theo yêu cầu;) Cụ thể, một _anchor_ trong một regex có nghĩa là gì. Nếu bạn muốn, tôi có thể đưa ra một lời giải thích đầy đủ, chi tiết hơn về công việc bên trong của neo;) – fge

1

(?=), một trống dương lookahead, sẽ luôn luôn phù hợp. Đó là một cách hackish để đặt giá trị của trận đấu thành công cuối cùng. (?!) là nghịch đảo của nó và sẽ không bao giờ khớp.

25

Mẫu regex rỗng khớp với chuỗi có độ dài bằng 0, nghĩa là chuỗi luôn phù hợp. Đây là một sự tiến triển rõ ràng:

'bbbbb' =~ /^(?:aaa|bbb)/ # Matches (Matches 3 "b"s, from pos 0 to 3) 
'bbbbb' =~ /^(?:aaa|bb)/ # Matches (Matches 2 "b"s, from pos 0 to 2) 
'bbbbb' =~ /^(?:aaa|b)/  # Matches (Matches 1 "b", from pos 0 to 1) 
'bbbbb' =~ /^(?:aaa|)/  # Matches (Matches 0 "b"s, from pos 0 to 0) 

Điều này có nghĩa rằng (?=) ("? Có vị trí này theo sau là một chuỗi zero-length") luôn luôn phù hợp và (?!) ("Có vị trí này không theo sau là một chuỗi số không dài?") không bao giờ phù hợp. Trên thực tế, (?!) được tối ưu hóa thành (*FAIL) kể từ khi giới thiệu sau trong 5,10.

(?!) hay còn gọi là (*FAIL) hữu ích khi buộc quay lại khi mẫu có tác dụng phụ.

'abcd' =~ /(.+?)(?{ print "$1\n" })(?!)/; 

Output:

a 
ab 
abc 
abcd 
b 
bc 
bcd 
c 
cd 
d 

Giải thích về dụ:

(?!) không phù hợp, do đó động cơ regex giữ cố gắng tìm một trận đấu bằng cách .+? trận đấu ngày càng nhiều nhân vật. Khi thất bại, công cụ regex cố gắng khớp ở vị trí bắt đầu sau.

Điều này được gọi là "backtracking". Đó là cách động cơ regex có thể khớp với 'aaaab' =~ /a*ab/. Lần đầu tiên thông qua, a* phù hợp với tất cả 4 a s, do đó, ab không khớp, do đó, công cụ phản hồi. Lần thứ hai thông qua, a* chỉ phù hợp với 3 trong số a s, cho phép ab và do đó toàn bộ mẫu phù hợp.

Các quy trình từng bước cho các ví dụ tôi ban cho sau:

  1. Bắt đầu phù hợp tại pos 0.
  2. (.+?) trận a tại pos 0
  3. (?{ print "$1\n" }) in a và phù hợp với không chars
  4. (?!) không khớp. ⇒ Quay lại!
  5. (.+?) trận ab tại pos 0
  6. (?{ print "$1\n" }) in ab và phù hợp với không chars
  7. (?!) không phù hợp. ⇒ Quay lại!
  8. (.+?) trận abc tại pos 0
  9. (?{ print "$1\n" }) in abc và phù hợp với không chars
  10. (?!) không phù hợp. ⇒ Quay lại!
  11. (.+?) trận abcd tại pos 0
  12. (?{ print "$1\n" }) in abcd và phù hợp với không chars
  13. (?!) không phù hợp. ⇒ Quay lại!
  14. (.+?) không thể khớp với bất kỳ mục nào khác tại đây. ⇒ Quay lại!
  15. Bắt đầu phù hợp tại pos 1.
  16. (.+?) trận b tại pos 1
  17. (?{ print "$1\n" }) in b và phù hợp với không chars
  18. (?!) không phù hợp. ⇒ Quay lại!
  19. ...
  20. (.+?) trận d tại pos 3
  21. (?{ print "$1\n" }) in d và phù hợp với không chars
  22. (?!) không phù hợp. ⇒ Quay lại!
  23. (.+?) không thể khớp với bất kỳ mục nào khác tại đây. ⇒ Quay lại!
  24. Bắt đầu khớp tại vị trí 4.
  25. (.+?) không khớp. ⇒ Quay lại!
  26. Mẫu không khớp.
+0

Tôi cần tìm hiểu nhiều hơn nữa để có thể hiểu ví dụ. Tôi hiểu '(. +?) '= khớp với chuỗi ngắn nhất có thể và thêm nó vào nhóm chụp, hiểu' push ... ', nhưng không biết tại sao nó lặp lại - vậy tại sao lại cho kết quả trên. Tôi chỉ là người mới bắt đầu - nhưng cảm ơn bạn. ;) – novacik

+0

'(?!)' Không khớp, vì vậy công cụ regex cố gắng tìm một kết quả phù hợp bằng cách '. +?' Khớp với nhiều ký tự hơn. Khi thất bại, công cụ regex cố gắng khớp ở vị trí bắt đầu sau. Điều này được gọi là "backtracking". Đó là cách động cơ regex có thể khớp với '' aaaab '= ~/a * ab/'. Lần đầu tiên thông qua, 'a *' khớp với tất cả 5 'a', do đó, 'ab' không khớp nhau, vì vậy nó backtracks. Lần thứ hai, 'a *' chỉ phù hợp với 4 '', cho phép 'ab' khớp với nhau. – ikegami

+0

... và tôi nghĩ rằng tôi biết regex – kizzx2

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