我正在編輯一個Perl文件,但我不明白這個正則表達式比較。有人可以向我解釋嗎?
if ($lines =~ m/(.*?):(.*?)$/g) { } ..
這裏會發生什麼? $lines
是來自文本文件的一行。
我正在編輯一個Perl文件,但我不明白這個正則表達式比較。有人可以向我解釋嗎?
if ($lines =~ m/(.*?):(.*?)$/g) { } ..
這裏會發生什麼? $lines
是來自文本文件的一行。
把它分解成幾部分:
$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;
所以,這會匹配":"
字符串(它可以匹配零個的字符,然後一個冒號,則該行年底前零個字符,$1
和$2
是空的字符串)或"abc:"
($1 = "abc"
,$2
是空字符串)或"abc:def:ghi"
($1 = "abc"
和$2 = "def:ghi"
)。
如果你傳入一個不匹配的行(看起來像這是字符串不包含冒號),那麼它將不處理括號內的代碼。但是,如果它匹配,那麼括號內的代碼就可以使用和處理特殊的變量(至少,直到下一個正則表達式出現,如果括號內有一個)。
(.*?)
捕獲任何字符,但儘可能少的字符。
因此,它看起來像<something>:<somethingelse><end of line>
模式,如果有多個:
字符串中,第一個將用作<something>
和<somethingelse>
之間的分隔符。
該行表示執行正則表達式匹配$lines
與正則表達式m/(.*?):(.*?)$/g
。如果找不到匹配,可以在$lines
和false
中找到匹配項,它將有效返回true
。
=~
的操作的說明:
二進制 「=〜」 結合一個標量表達式 到一個模式匹配。某些操作 默認爲搜索或修改字符串$ _ 。該操作員使其他 字符串的操作可以在 上運行。正確的參數是搜索 模式,替代或 音譯。左邊的參數是 應該搜索什麼, 替代,或音譯代替 的默認$ _。當在標量 上下文中使用時,返回值通常爲 指示 操作的成功。
正則表達式本身是:
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)
因此,如果針對該正則表達式匹配$lines
,它會進入有條件的部分,否則將false
,將跳過它。
有一個工具可以幫助理解正則表達式:YAPE::Regex::Explain。
忽略g
修改,這裏沒有必要:
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
----------------------------------------------------------------------
這該死的整潔! – 2010-09-22 18:37:19
這是由誰知道太多關於正則表達式或者不太瞭解$'
和$`變量的人寫的。
這可能是寫成
if ($lines =~ /:/) {
... # use $` ($PREMATCH) instead of $1
... # use $' ($POSTMATCH) instead of $2
}
或
if (($var1,$var2) = split /:/, $lines, 2 and defined($var2)) {
... # use $var1, $var2 instead of $1,$2
}
如果要使用/:/,請使用Perl 5.10中的/ p標誌和$ {^ PREMATCH}和$ {^ POSTMATCH}變量。不過,我寧願分手,因爲這就是實際發生的事情。 – 2010-09-22 20:16:53
貌似第一個'(。*?)'總是會匹配空字符串。 – 2010-09-22 16:40:00
並非總是如此。它會匹配所有字符到第一個冒號。 – CanSpice 2010-09-22 16:43:44