2010-09-22 42 views
5

Tôi đang chỉnh sửa tệp Perl, nhưng tôi không hiểu so sánh regexp này. Ai đó có thể giải thích cho tôi không?

if ($lines =~ m/(.*?):(.*?)$/g) { } .. 

Điều gì xảy ra ở đây? $lines là một dòng từ tệp văn bản.

+0

Hình như đầu tiên '(. *?)' Sẽ luôn luôn phù hợp với chuỗi rỗng. –

+1

Không phải lúc nào. Nó sẽ khớp với tất cả các ký tự lên đến dấu hai chấm đầu tiên. – CanSpice

Trả lời

11

Phá vỡ nó ra thành phần:

$lines =~ m/ (.*?)  # Match any character (except newlines) 
         # zero or more times, not greedily, and 
         # stick the results in $1. 
      :   # Match a colon. 
      (.*?)  # Match any character (except newlines) 
         # zero or more times, not greedily, and 
         # stick the results in $2. 
      $   # Match the end of the line. 
      /gx; 

Vì vậy, điều này sẽ phù hợp với chuỗi như ":" (nó phù hợp với không ký tự, sau đó một dấu hai chấm, sau đó không ký tự trước khi kết thúc dòng, $1$2 đang rỗng dây) hoặc "abc:" ($1 = "abc", $2 là một chuỗi trống) hoặc "abc:def:ghi" ($1 = "abc"$2 = "def:ghi").

Và nếu bạn vượt qua một dòng không khớp (có vẻ như nếu chuỗi này không chứa dấu hai chấm), thì nó sẽ không xử lý mã nằm trong dấu ngoặc đơn. Nhưng nếu nó phù hợp, thì mã trong ngoặc đơn có thể sử dụng và xử lý các biến số $1$2 đặc biệt (ít nhất, cho đến khi cụm từ thông dụng tiếp theo xuất hiện, nếu có một trong ngoặc).

1

(.*?) chụp bất kỳ ký tự nào, nhưng ít nhất có thể.

Vì vậy, nó sẽ tìm các mẫu như <something>:<somethingelse><end of line> và nếu có nhiều : trong chuỗi, chuỗi đầu tiên sẽ được sử dụng làm dải phân cách giữa <something><somethingelse>.

2

Dòng đó nói để thực hiện đối sánh cụm từ thông dụng trên $lines với regex m/(.*?):(.*?)$/g. Nó có hiệu quả sẽ trở lại true nếu một kết quả phù hợp có thể được tìm thấy trong $linesfalse nếu không thể tìm thấy.

Giải thích về các nhà điều hành =~:

Binary "= ~" liên kết với một biểu thức vô hướng đến một mô hình phù hợp. Một số hoạt động nhất định tìm kiếm hoặc sửa đổi chuỗi $ _ theo mặc định. Toán tử này làm cho loại hoạt động hoạt động này trên một số chuỗi khác. Đối số phù hợp là tìm kiếm mẫu, thay thế hoặc chuyển ngữ. Đối số bên trái là những gì được cho là được tìm kiếm, được thay thế hoặc được chuyển ngữ thay vì của $ _ mặc định. Khi được sử dụng trong ngữ cảnh vô hướng, giá trị trả lại thường là cho biết sự thành công của hoạt động .

Các regex chính nó là:

m/ #Perform a "match" operation 
(.*?) #Match zero or more repetitions of any characters, but match as few as possible (ungreedy) 
:  #Match a literal colon character 
(.*?) #Match zero or more repetitions of any characters, but match as few as possible (ungreedy) 
$  #Match the end of string 
/g #Perform the regex globally (find all occurrences in $line) 

Vì vậy, nếu $lines trận đấu với regex đó, nó sẽ đi vào phần điều kiện, nếu không nó sẽ false và sẽ bỏ qua nó.

9

Có một công cụ giúp hiểu các regex: YAPE::Regex::Explain.

Lờ đi g sửa đổi, đó là không cần thiết ở đây:

use strict; 
use warnings; 
use YAPE::Regex::Explain; 

my $re = qr/(.*?):(.*?)$/; 
print YAPE::Regex::Explain->new($re)->explain(); 

__END__ 

The regular expression: 

(?-imsx:(.*?):(.*?)$) 

matches as follows: 

NODE      EXPLANATION 
---------------------------------------------------------------------- 
(?-imsx:     group, but do not capture (case-sensitive) 
         (with^and $ matching normally) (with . not 
         matching \n) (matching whitespace and # 
         normally): 
---------------------------------------------------------------------- 
    (      group and capture to \1: 
---------------------------------------------------------------------- 
    .*?      any character except \n (0 or more times 
          (matching the least amount possible)) 
---------------------------------------------------------------------- 
)      end of \1 
---------------------------------------------------------------------- 
    :      ':' 
---------------------------------------------------------------------- 
    (      group and capture to \2: 
---------------------------------------------------------------------- 
    .*?      any character except \n (0 or more times 
          (matching the least amount possible)) 
---------------------------------------------------------------------- 
)      end of \2 
---------------------------------------------------------------------- 
    $      before an optional \n, and the end of the 
          string 
---------------------------------------------------------------------- 
)      end of grouping 
---------------------------------------------------------------------- 

Xem thêm perldoc perlre.

+1

Thật đáng yêu! –

3

Nó được viết bởi một người biết quá nhiều về các cụm từ thông dụng hoặc không đủ về các biến số $'$`.

Điều này có thể đã được viết như

if ($lines =~ /:/) { 
    ... # use $` ($PREMATCH) instead of $1 
    ... # use $' ($POSTMATCH) instead of $2 
} 

hoặc

if (($var1,$var2) = split /:/, $lines, 2 and defined($var2)) { 
    ... # use $var1, $var2 instead of $1,$2 
} 
+1

Nếu bạn muốn sử dụng /: /, hãy sử dụng cờ/p và biến $ {^ PREMATCH} và $ {^ POSTMATCH} từ Perl 5.10. Tuy nhiên, tôi thích chia rẽ hơn vì đó là điều thực sự xảy ra. –

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