2010-06-26 28 views
5

tôi đang học Perl và nhận thấy một điều không minh bạch khá đặc biệt - cố gắng để phù hợp với một trong nhiều điều kiện regex trong một thời gian lặp kết quả trong vòng lặp mà diễn ra trong vô cực:Perl: Nhiều điều kiện regex toàn cầu "hoặc" được phân tách trong khi khối dẫn đến vòng lặp vô hạn?

#!/usr/bin/perl 

my $hivar = "this or that"; 

while ($hivar =~ m/this/ig || $hivar =~ m/that/ig) { 
     print "$&\n"; 
} 

Kết quả của chương trình này là:

this 
that 
that 
that 
that 
[...] 

Tôi tự hỏi tại sao điều này? Có bất kỳ cách giải quyết mà ít vụng về hơn thế này:

#!/usr/bin/perl 

my $hivar = "this or that"; 

while ($hivar =~ m/this|that/ig) { 
     print "$&\n"; 
} 

Đây là một việc đơn giản hóa của một vấn đề thực tế tôi đang gặp phải, và trong khi tôi quan tâm đến điều này trong một quan điểm thực tế, tôi cũng muốn biết những gì đằng sau hậu trường đang kích hoạt hành vi này. Đây là một câu hỏi có vẻ không tương thích với Google.

Cảm ơn!

Tom

+0

Hobbes giải thích nó khá tốt bên dưới, nhưng cũng vậy Wall, Schwartz, et al .: http://perldoc.perl.org/perlretut.html#Global-matching – msw

+0

Bạn có thể muốn xem ở đây để xem liệu Regexp :: Gói lắp ráp có thể giúp bạn: http://stackoverflow.com/questions/1478083/how-can-i-efficiently-match-many-different-regex-patterns-in-perl –

Trả lời

16

Cái này là có một giá trị ẩn liên quan đến với mỗi chuỗi, không với mỗi trận đấu, điều khiển, nơi một trận đấu /g sẽ cố gắng tiếp tục, và truy cập thông qua pos($string). Chuyện gì xảy ra là:

  1. pos($hivar) là 0, /this/ trận đấu ở vị trí 0 và reset pos($hivar) đến 4. Trận đấu thứ hai là không cố gắng vì hoặc nhà điều hành đã thành sự thật. $& trở thành "này" và được in.
  2. pos($hivar) là 4, /this/ không khớp vì không có "vị trí này" ở vị trí 4 trở lên. Kết quả không khớp đặt lại pos($hivar) thành 0.
  3. /that/ đối sánh tại vị trí 6 và đặt lại pos($hivar) thành 10. $& trở thành "đó" và được in.
  4. pos($hivar) là 10, /this/ không khớp vì không có "vị trí này" ở vị trí 10 trở lên. Kết quả không khớp đặt lại pos($hivar) thành 0.
  5. /that/ đối sánh tại vị trí 6 và đặt lại pos($hivar) thành 10. $& trở thành "đó" và được in.

và các bước 4 và 5 lặp lại vô thời hạn.

Thêm cờ c regex (yêu cầu động cơ không đặt lại pos khi kết hợp không thành công) giải quyết vấn đề trong mã mẫu bạn cung cấp, nhưng có thể hoặc không phải là giải pháp lý tưởng cho vấn đề phức tạp hơn.

+2

giải thích rất rõ, cookie cho u. – Prix

+0

Thật vậy. Đặt tốt. Cảm ơn bạn! –

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