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:
- Bắt đầu phù hợp tại pos 0.
(.+?)
trận a
tại pos 0
(?{ print "$1\n" })
in a
và phù hợp với không chars
(?!)
không khớp. ⇒ Quay lại!
(.+?)
trận ab
tại pos 0
(?{ print "$1\n" })
in ab
và phù hợp với không chars
(?!)
không phù hợp. ⇒ Quay lại!
(.+?)
trận abc
tại pos 0
(?{ print "$1\n" })
in abc
và phù hợp với không chars
(?!)
không phù hợp. ⇒ Quay lại!
(.+?)
trận abcd
tại pos 0
(?{ print "$1\n" })
in abcd
và phù hợp với không chars
(?!)
không phù hợp. ⇒ Quay lại!
(.+?)
không thể khớp với bất kỳ mục nào khác tại đây. ⇒ Quay lại!
- Bắt đầu phù hợp tại pos 1.
(.+?)
trận b
tại pos 1
(?{ print "$1\n" })
in b
và phù hợp với không chars
(?!)
không phù hợp. ⇒ Quay lại!
- ...
(.+?)
trận d
tại pos 3
(?{ print "$1\n" })
in d
và phù hợp với không chars
(?!)
không phù hợp. ⇒ Quay lại!
(.+?)
không thể khớp với bất kỳ mục nào khác tại đây. ⇒ Quay lại!
- Bắt đầu khớp tại vị trí 4.
(.+?)
không khớp. ⇒ Quay lại!
- Mẫu không khớp.
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
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