perl正則表達式

一、簡介
二、匹配操作符
三、模式中的特殊字符
1、字符
2、字符 []和[^]
3、字符 +,*和?
4、轉義字符
5、匹配任意字母或數字
6、錨模式
7、模式中的變量替換
8、字符範圍轉義前綴
9、匹配任意字符
10、匹配指定數目的字符
11、指定選項
12、模式的部分重用
13、轉義和特定字符的執行次序
14、指定模式定界符
15、模式次序變量
四、模式匹配選項
1、匹配所有可能的模式(g選項)
2、忽略大小寫(i選項)例
3、將字符串看作多行(m選項)
4、只執行一次變量替換例
5、將字符串看作單行例
6、在模式中忽略空格
五、替換操作符
六、翻譯操作符
七、擴展模式匹配
1、不存貯括號內的匹配內容
2、內嵌模式選項
3、肯定的和否定的預見匹配
4、模式註釋
八、 注意貪婪性

九、正則表達式的返回值

一、簡介

模式指在字符串中尋找的特定序列的字符,由反斜線包含:/def/即模式def。其用法如結合函數split將字符串用某模式分成多個單詞:@array = split(/ /, $line);

 

二、匹配操作

匹配操作符 =~、!~
=~檢驗匹配是否成功:$result = $var =~ /abc/;若在該字符串中找到了該模式,則返回非零值,即true,不匹配則返回0,即false。!~則相反。

這兩個操作符適於條件控制中,如:
if ($question =~ /please/) {
print ("Thank you for being polite!\n");
}
else {
print ("That was not very polite!\n");

}

 

三、模式中的特殊字符
PERL在模式中支持一些特殊字符,可以起到一些特殊的作用。
1、字符
意味着一個或多個相同的字符,如:/de f/指def、deef、deeeeef等。它儘量匹配儘可能多的相同字符,如/ab /在字符串abbc中匹配的將是abb,而不是ab。
當一行中各單詞間的空格多於一個時,可以如下分割:
@array = split (/ /, $line);

注:split函數每次遇到分割模式,總是開始一個新單詞,因此若$line以空格打頭,則@array的第一個元素即爲空元素。但其可以區分是否真有單詞,如若$line中只有空格,則@array則爲空數組。且上例中TAB字符被當作一個單詞。注意修正。

 

2、字符 []和[^]

[]意味着匹配一組字符中的一個,如/a[0123456789]c/將匹配a加數字加c的字符串。與 聯合使用例:/d[eE] f/匹配def、dEf、deef、dEdf、dEEEeeeEef等。^表示除其之外的所有字符,如:/d[^deE]f/匹配d加非e字符加f的字符 串。

 

3、字符 *和?

它們與 類似,區別在於*匹配0個、1個或多個相同字符,?匹配0個或1個該字符,+告訴引擎匹配前導字符1次或多次。如/de*f/匹配df、def、deeeef等;/de?f/匹配df或def。

 

4、轉義字符

如果你想在模式中包含通常被看作特殊意義的字符,須在其前加斜線"\"。如:/\* /中\*即表示字符*,而不是上面提到的一個或多個字符的含義。斜線的表示爲/\\/。在PERL5中可用字符對\Q和\E來轉義。

 

5、匹配任意字母或數字

上面提到模式/a[0123456789]c/匹配字母a加任意數字加c的字符串,另一種表示方法爲:/a[0-9]c/,類似的,[a-z]表示任意小寫字母,[A-Z]表示任意大寫字母。任意大小寫字母、數字的表示方法爲:/[0-9a-zA-Z]/。

 

6、錨模式
錨 描述
^ 或 \A 僅匹配串首
$ 或 \Z 僅匹配串尾
\b 匹配單詞邊界
\B 單詞內部匹配

例1:/^def/只匹配以def打頭的字符串,/$def/只匹配以def結尾的字符串,結合起來的/^def$/只匹配字符串def(?)。\A和\Z在多行匹配時與^和$不同。
例2:檢驗變量名的類型:
if ($varname =~ /^\$[A-Za-z][_0-9a-zA-Z]*$/) {
print ("$varname is a legal scalar variable\n");
} elsif ($varname =~ /^@[A-Za-z][_0-9a-zA-Z]*$/) {
print ("$varname is a legal array variable\n");
} elsif ($varname =~ /^[A-Za-z][_0-9a-zA-Z]*$/) {
print ("$varname is a legal file variable\n");
} else {
print ("I dont understand what $varname is.\n");
}
例 3:\b在單詞邊界匹配:/\bdef/匹配def和defghi等以def打頭的單詞,但不匹配abcdef。/def\b/匹配def和 abcdef等以def結尾的單詞,但不匹配defghi,/\bdef\b/只匹配字符串def。注意:/\bdef/可匹配$defghi,因爲$並 不被看作是單詞的部分。

例4:\B在單詞內部匹配:/\Bdef/匹配abcdef等,但不匹配def;/def\B/匹配defghi等;/\Bdef\B/匹配cdefg、abcdefghi等,但不匹配def,defghi,abcdef。

 

7、模式中的變量替換
將句子分成單詞:
$pattern = "[\\t ] ";

@words = split(/$pattern/, $line);

 

8、字符範圍轉義
E 轉義字符 描述 範圍
\d 任意數字 [0-9]
\D 除數字外的任意字符 [^0-9]
\w 任意單詞字符 [_0-9a-zA-Z]
\W 任意非單詞字符 [^_0-9a-zA-Z]
\s 空白 [ \r\t\n\f]
\S 非空白 [^ \r\t\n\f]

例:/[\da-z]/匹配任意數字或小寫字母。

 

9、匹配任意字符

字符"."匹配除換行外的所有字符,通常與*合用。

 

10、匹配指定數目的字符

字符對{}指定所匹配字符的出現次數。如:/de{1,3}f/匹配def,deef和deeef;/de{3}f/匹配deeef;/de{3,}f/匹配不少於3個e在d和f之間;/de{0,3}f/匹配不多於3個e在d和f之間。

 

11、指定選項
字符"|"指定兩個或多個選擇來匹配模式。如:/def|ghi/匹配def或ghi。
例:檢驗數字表示合法性
if ($number =~ /^-?\d $|^-?0[xX][\da-fa-F] $/) {
print ("$number is a legal integer.\n");
} else {
print ("$number is not a legal integer.\n");
}

其中 ^-?\d $ 匹配十進制數字,^-?0[xX][\da-fa-F] $ 匹配十六進制數字。

 

12、模式的部分重用
當模式中匹配相同的部分出現多次時,可用括號括起來,後面用\n來多次引用,以簡化表達式:
/\d{2}([\W])\d{2}\1\d{2}/ 匹配:
12-05-92
26.11.87
07 04 92等
注意:/\d{2}([\W])\d{2}\1\d{2}/ 不同於/(\d{2})([\W])\1\2\1/ ,後者只匹配形如17-17-17的字符串,而不匹配17-05-91等。
在/\d{2}([\W])\d{2}\1\d{2}/中,\1代表}([\W]), 而在/(\d{2})([\W])\1\2\1/中,\1代表(\d{2}),\2代表([\W])。


13、轉義和特定字符的執行次序
象操作符一樣,轉義和特定字符也有執行次序:

特殊字符 描述
() 模式內存 ,可以在後面使用\n來使用。
* ? {} 出現次數
^ $ \b \B 錨
| 選項

14、指定模式定界符
缺省的,模式定界符爲反斜線/,但其可用字母m自行指定,如:
m!/u/jqpublic/perl/prog1! 等價於/\/u\/jqpublic\/perl\/prog1/

注:當用字母作爲定界符時,不做變量替換;當用特殊字符作爲定界符時,其轉義功能或特殊功能即不能使用。

 

15、模式次序變量
在模式匹配後調用重用部分的結果可用變量$n,全部的結果用變量$&。
$string = "This string contains the number 25.11.";
$string =~ /-?(\d )\.?(\d )/; # 匹配結果爲25.11
$integerpart = $1; # now $integerpart = 25
$decimalpart = $2; # now $decimalpart = 11

$totalpart = $&; # now totalpart = 25.11

實例:

$lastLabel =~ /$LabelLetter((\d\d\d)(\.\d\d\d)?)([a-z]?)/i
# Ex: for 031.100A
# $1 = 031.100, $2 = 031, $3 = .100, $4 = A

 

四、模式匹配選項
選項 描述
g 匹配所有可能的模式
i 忽略大小寫
m 將串視爲多行
o 只賦值一次
s 將串視爲單行
x 忽略模式中的空白

1、匹配所有可能的模式(g選項)
@matches = "balata" =~ /.a/g; # now @matches = ("ba", "la", "ta")
匹配的循環:
while ("balata" =~ /.a/g) {
$match = $&;
print ("$match\n");
}
結果爲:
ba
la
ta
當使用了選項g時,可用函數pos來控制下次匹配的偏移:
$offset = pos($string);

pos($string) = $newoffset;

 

2、忽略大小寫(i選項)例

/de/i 匹配de,dE,De和DE。

 

3、將字符串看作多行(m選項)

在此情況下,^符號匹配字符串的起始或新的一行的起始;$符號匹配任意行的末尾。

 

4、只執行一次變量替換例
$var = 1;
$line = ;
while ($var < 10) {
$result = $line =~ /$var/o;
$line = ;
$var ;
}

每次均匹配/1/。

 

5、將字符串看作單行例

/a.*bc/s匹配字符串axxxxx \nxxxxbc,但/a.*bc/則不匹配該字符串。

 

6、在模式中忽略空格

/\d{2} ([\W]) \d{2} \1 \d{2}/x等價於/\d{2}([\W])\d{2}\1\d{2}/。

 

五、替換操作符
語法爲s/pattern/replacement/,其效果爲將字符串中與pattern匹配的部分換成replacement。如:
$string = "abc123def";
$string =~ s/123/456/; # now $string = "abc456def";
在替換部分可使用模式次序變量$n,如s/(\d )/[$1]/,但在替換部分不支持模式的特殊字符,如{},*, 等,如s/abc/[def]/將把abc替換爲[def]。
替換操作符的選項如下表:
選項 描述
g 改變模式中的所有匹配
i 忽略模式中的大小寫
e 替換字符串作爲表達式
m 將待匹配串視爲多行
o 僅賦值一次
s 將待匹配串視爲單行
x 忽略模式中的空白

注:e選項把替換部分的字符串看作表達式,在替換之前先計算其值,如:
$string = "0abc1";

$string =~ s/[a-zA-Z] /$& x 2/e; # now $string = "0abcabc1"

 

六、翻譯操作符
這是另一種替換方式,語法如:tr/string1/string2/。同樣,string2爲替換部分,但其效 果是把string1中的第一個字符替換 爲string2中的第一個字符,把string1中的第二個字符替換爲string2中的第二個字符,依此類推。如:
$string = "abcdefghicba";
$string =~ tr/abc/def/; # now string = "defdefghifed"
當string1比string2長時,其多餘字符替換爲string2的最後一個字符;當string1中同一個字符出現多次時,將使用第一個替換字符。
翻譯操作符的選項如下:

選項 描述
c 翻譯所有未指定字符
d 刪除所有指定字符
s 把多個相同的輸出字符縮成一個

如$string =~ tr/\d/ /c;把所有非數字字符替換爲空格。$string =~ tr/\t //d;刪除tab和空格; $string =~ tr/0-9/ /cs;把數字間的其它字符替換爲一個空格。

七、擴展模式匹配
PERL支持PERL4和標準UNIX模式匹配操作所沒有的一些模式匹配能力。其語法爲:(?pattern),其中c是一個字符,pattern是起作用的模式或子模式。
1、不存貯括號內的匹配內容
在PERL的模式中,括號內的子模式將存貯在內存中,此功能即取消存貯該括號內的匹配內容,如/(?:a|b|c)(d|e)f\1/中的\1表示已匹配的d或e,而不是a或b或c。
2、內嵌模式選項
通常模式選項置於其後,有四個選項:i、m、s、x可以內嵌使用,語法爲:/(?option)pattern/,等價於/pattern/option。
3、肯定的和否定的預見匹配
肯定的預見匹配語法爲/pattern(?=string)/,其意義爲匹配後面爲string的模式,相反的,(?!string)意義爲匹配後面非string的模式,如:
$string = "25abc8";
$string =~ /abc(?=[0-9])/;
$matched = $&; # $&爲已匹配的模式,此處爲abc,而不是abc8
4、模式註釋
PERL5中可以在模式中用?#來加註釋,如:
if ($string =~ /(?i)[a-z]{2,3}(?# match two or three alphabetic characters)/ {
...

}

 

八、 注意貪婪性

假設你想用一個正則表達式匹配一個HTML標籤。你知道輸入將會是一個有效的HTML文件,因此正則表達式不需要排除那些無效的標籤。所以如果是在兩個尖括號之間的內容,就應該是一個HTML標籤。

許多正則表達式的新手會首先想到用正則表達式<< <.+> >>,他們會很驚訝的發現,對於測試字符串,“This is a <EM>first</EM> test”,你可能期望會返回<EM>,然後繼續進行匹配的時候,返回</EM>。

但事實是不會。正則表達式將會匹配“<EM>first</EM>”。很顯然這不是我們想要的結果。原因在於“+”是貪婪 的。也就是說,“+”會導致正則表達式引擎試圖儘可能的重複前導字符。只有當這種重複會引起整個正則表達式匹配失敗的情況下,引擎會進行回溯。也就是說, 它會放棄最後一次的“重複”,然後處理正則表達式餘下的部分。

和“+”類似,“?*”的重複也是貪婪的。

用懶惰性取代貪婪性
一個用於修正以上問題的可能方案是用“+”的惰性代替貪婪性。你可以在“+”後面緊跟一個問號“?”來達到這一點。“*”,“{}”和“?”表示的重複也可以用這個方案。因此在上面的例子中我們可以使用“<.+?>”。讓我們再來看看正則表達式引擎的處理過程。

再一次,正則表達式記號“<”會匹配字符串的第一個“<”。下一個正則記號是“.”。這次是一個懶惰的“+”來重複上一個字符。這告訴 正則引擎,儘可能少的重複上一個字符。因此引擎匹配“.”和字符“E”,然後用“>”匹配“M”,結果失敗了。引擎會進行回溯,和上一個例子不同, 因爲是惰性重複,所以引擎是擴展惰性重複而不是減少,於是“<.+”現在被擴展爲“<EM”。引擎繼續匹配下一個記號“>”。這次得到 了一個成功匹配。引擎於是報告“<EM>”是一個成功的匹配。整個過程大致如此。


惰性擴展的一個替代方案
我們還有一個更好的替代方案。可以用一個貪婪重複與一個取反字符集:“<[^>]+>”。

 

九、正則表達式的返回值
正則表達式匹配後返回的爲數組或長度,取決於表達式中是否有()或者接收的變量類型

 

複製代碼
$a = 'RRR3ttt';
@yy = $a=~/RRR.*ttt/;
$numofyy = $a=~/RRR.*ttt/;
print "@yy\n";
print "$numofyy\n" ;

@yy2 = $a=~/(RRR).*(ttt)/;
$numofyy2 = $a=~/(RRR).*(ttt)/;
print "@yy2\n";
print "$numofyy2\n";
print "$1 $2";
複製代碼

 

結果:

1
1
RRR ttt
1
RRR ttt

 

發佈了71 篇原創文章 · 獲贊 27 · 訪問量 100萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章