正則表達(dá)式比此處所介紹的主題要大得多,確信你理解了這些概念。對(duì)于教程, 可以參閱?perlrequick?或?perlretut。而權(quán)威的文檔,則能夠參閱?perlre。
m//
?和?s///
?操作符分別返回匹配或替換的數(shù)目。你既可以直接使用該數(shù)目, 也可以檢查其真值。
if ( $str =~ /Diggle|Shelley/ ) {
print "We found Pete or Steve!\n";
}
if ( my $n = ($str =~ s/this/that/g) ) {
print qq{Replaced $n occurrence(s) of "this"\n};
}
除非匹配成功,捕獲變量?$1
?等是無效的,并且它們不會(huì)被清理。
# BAD: Not checked, but at least it "works".
my $str = 'Perl 101 rocks.';
$str =~ /(\d+)/;
print "Number: $1"; # Prints "Number: 101";
# WORSE: Not checked, and the result is not what you'd expect
$str =~ /(Python|Ruby)/;
print "Language: $1"; # Prints "Language: 101";
你必須檢查匹配的返回值:
# GOOD: Check the results
my $str = 'Perl 101 rocks.';
if ( $str =~ /(\d+)/ ) {
print "Number: $1"; # Prints "Number: 101";
}
if ( $str =~ /(Python|Ruby)/ ) {
print "Language: $1"; # Never gets here
}
/i
:不區(qū)分大小寫/g
:匹配多次$var = "match match match";
while ($var =~ /match/g) { $a++; }
print "$a\n"; # prints 3
$a = 0;
$a++ foreach ($var =~ /match/g);
print "$a\n"; # prints 3
/m
:更改?^
?和?$
?的意義正常情況下,^
?意為字符串的開頭,而?$
?為字符串的結(jié)尾。/m
?使它們分別意為行首和行尾。
$str = "one\ntwo\nthree";
@a = $str =~ /^\w+/g; # @a = ("one");
@b = $str =~ /^\w+/gm; # @b = ("one","two","three")
不管是否有?/m
,使用?\A
?和?\z
?來匹配字符串的開頭和結(jié)尾。\Z
?除了會(huì)忽略最后的換行之外,與?\z
?相同,
/s
:使?.
?也匹配換行$str = "one\ntwo\nthree\n";
$str =~ /^(.{8})/s;
print $1; # prints "one\ntwo\n"
$1
?及之友捕獲括號(hào)對(duì)的內(nèi)容被存儲(chǔ)到數(shù)字變量中。括號(hào)從左到右分配:
my $str = "abc";
$str =~ /(((a)(b))(c))/;
print "1: $1 2: $2 3: $3 4: $4 5: $5\n";
# prints: 1: abc 2: ab 3: a 4: b 5: c
捕獲括號(hào)及變量的數(shù)目沒有上限。
?:
?避免捕獲如果括號(hào)后緊接著??:
,那么該分組不會(huì)被捕獲。在你不想保存匹配的內(nèi)容時(shí) 會(huì)有用:
my $str = "abc";
$str =~ /(?:a(b)c)/;
print "$1\n"; # prints "b"
/x
?選項(xiàng)使正則表達(dá)式更易讀如果你在使用正則表達(dá)式時(shí)玩了些花樣,那么為它寫注釋。你可以使用?/x
?選項(xiàng)達(dá)到目的。
丑陋的龐然大物:
my ($num) = $ARGV[0] =~ m/^\+?((?:(?<!\+)-)?(?:\d*.)?\d+)$/x;
使用?/x
?允許的空白和注釋更可讀:
my ($num) =
$ARGV[0] =~ m/^ \+? # An optional plus sign, to be discarded
( # Capture...
(?:(?<!\+)-)? # a negative sign, if there's no plus behind it,
(?:\d*.)? # an optional number, followed by a point if a decimal,
\d+ # then any number of numbers.
)$/x;
除非被轉(zhuǎn)義,空白和注釋將被去除。
\Q
?和?\E
?自動(dòng)引起正則表達(dá)式這會(huì)自動(dòng)轉(zhuǎn)義正則表達(dá)式的元字符。不會(huì)轉(zhuǎn)義?$
?符號(hào)。
my $num = '3.1415';
print "ok 1\n" if $num =~ /\Q3.14\E/;
$num = '3X1415';
print "ok 2\n" if $num =~ /\Q3.14\E/;
print "ok 3\n" if $num =~ /3.14/;
輸出:
ok 1
ok 3
s///
?使用?/e
?選項(xiàng)來執(zhí)行代碼這將允許任意代碼替換正則表達(dá)式中的字符串。
my $str = "AbCdE\n";
$str =~ s/(\w)/lc $1/eg;
print $str; # prints "abcde"
必要時(shí)使用?$1
?及之友。
study
study
?在多數(shù)情況下都無用。它所做的是創(chuàng)建一個(gè)每個(gè)單字節(jié)字符首次出現(xiàn)在字符串中 的位置的表。這意味著如果你有 1,000 個(gè)字符長的字符串,你要尋找由一個(gè)常量字符開頭 的各種字符串,匹配器可以立即跳轉(zhuǎn)到正確的位置。例如:
"This is a very long [... 900 characters skipped...] string that I have here,
ending at position 1000"
現(xiàn)在,如果你要匹配正則表達(dá)式?/Icky/
,匹配器將試圖尋找第一個(gè)匹配的字母?I
。在 找到它之前得掃描前面的 900+ 個(gè)字符。但?study
?創(chuàng)建了一個(gè) 256 個(gè)字節(jié)第一次出現(xiàn) 的地方的表。所以掃描器能夠立即跳轉(zhuǎn)到那個(gè)位置來開始匹配。
譯注:這里沒有考慮到多字節(jié)字符。
re => debug
?調(diào)試正則表達(dá)式-Mre=debug
更多建議: