學(xué)習(xí)筆記 如何實(shí)現(xiàn)Perl正則表達(dá)式匹配
本文和大家重點(diǎn)討論一下Perl正則表達(dá)式匹配的用法,在學(xué)習(xí)Perl語言的過程中Perl正則表達(dá)式有很多值得學(xué)習(xí)的地方,這里和大家分享一下Perl正則表達(dá)式匹配方面的知識(shí)。
Perl正則表達(dá)式詳解
Perl正則表達(dá)式有三種形式:匹配、替換和轉(zhuǎn)換。接下來對(duì)每一個(gè)表達(dá)式給出詳盡解釋。
Perl正則表達(dá)式匹配:m/<regexp>/這種形式表明在//內(nèi)部的正則表達(dá)將用于匹配=~或!~左邊的標(biāo)量。為了語法上的簡(jiǎn)化用/<regexp>/,略去m。
Perl正則表達(dá)式替換:s/<regexp>/<substituteText>/這種形式表明Perl正則表達(dá)式<regexp>將被文本<substituteText>替換,為了語法的簡(jiǎn)化用/<regexp>/<substituteText>略去s。
Perl正則表達(dá)式轉(zhuǎn)換:tr/<charClass>/<substituteClass>/這種形式包含一系列的字符—/<charClass>—同時(shí)把它們替換為<substituteClass>。
注意轉(zhuǎn)換<tr>并不真正是一個(gè)Perl正則表達(dá)式,但是對(duì)于用Perl正則表達(dá)式難于處理的數(shù)據(jù)常使用它來進(jìn)行操縱。因此,tr/[0-9]/9876543210.組成1223456789,987654321等字符串。
◆通過使用=~(用英語講:does,與“進(jìn)行匹配”同)和!~(英語:doesn't,與“不匹配”同)把這些表達(dá)式捆綁到標(biāo)量上。作為這種類型的例子,下面我們給出六個(gè)示例Perl正則表達(dá)式及相應(yīng)的定義:
- $scalarName=~s/a/b;#substitutethecharacteraforb,andreturntrueifthiscanhappern
- $scalarName=~m/a;#doesthescalar$scalarNamehaveanainit?
- $scalarName=~tr/A-Z/a-z/;#translateallcapitalletterwithlowercaseones,andreturntureifthishappens
- $scalarName!~s/a/b/;#substitutethecharacteraforb,andreturnfalseifthisindeedhappens.
- $scalarName!~m/a/;#doesthescalar$scalarNamematchthecharactera?Returnfalseifitdoes.
- $scalarName!~tr/0-9/a-j/;#translatethedigitsforthelettersathruj,andreturnfalseifthishappens
.如果我們輸入像hornedtoad=~m/toad/這樣的代碼,則出現(xiàn)圖9-1所示情況:
另外,如果讀者正在對(duì)特定變量$_進(jìn)行匹配(讀者可能在while循環(huán),map或grep中使用),則可以不用!~和=~。因而,以下所有代碼都會(huì)合法:
- my@elemente=('al','a2','a3','a4','a5');
- foreach(@elements){s/a/b/;}
程序使@elements等于b1,b2.b3,b4,b5。另外:
while(<$FD>){printif(m/ERBOR/);}
打印所有包含error字符串的行:
if(grep(/pattern/,@lines)){print"thevariable\@lineshaspatterninit!\n";}
打印所有包含模式pattern內(nèi)容的行,這直接引入下一原則。
◆Perl正則表達(dá)式匹配。
Perl正則表達(dá)式盡在標(biāo)量上匹配,注意這里標(biāo)量的重要性,如果讀者試一試如下代碼:
- @arrayName=('variablel','variable2');
- @arrayName=~m/variable/;#looksfor'variable'inthearray?No!usegrepinstead
那么@arrayName匹配不成功!@arrayName被Perl解釋為2,于是這意味著讀者在輸入:
'2'=~m/variable/;
至少講這不能給出預(yù)想的結(jié)果。如果讀者想這樣做,輸人為:
grep(m/variable/,@arrayName);
該函數(shù)通過@arrayName中的每一個(gè)元素進(jìn)行循環(huán),返回(在標(biāo)量環(huán)境中)匹配的次數(shù),同時(shí)在數(shù)組環(huán)境中返回匹配元素的實(shí)際列表。
◆對(duì)于給定的模式串,Perl正則表達(dá)式只匹配最早出現(xiàn)的匹配項(xiàng)。匹配時(shí)缺省一次只匹配或替換一次。
這個(gè)原則使用稱為“回溯”的過程指出如何匹配一個(gè)給定的字符串;如果發(fā)現(xiàn)了一個(gè)局部匹配進(jìn)而找到使該匹配無效的東西,Perl正則表達(dá)式在字符串中“回溯”最小的可能數(shù)量,這個(gè)數(shù)量的字符要保證不丟失任何匹配。
對(duì)于理解Perl正則表達(dá)式正在做什么,這個(gè)原則是最有幫助的一個(gè),同時(shí)不需要與Perl一樣的形式來理解它正在做什么。假定有如下模式:'Sillypeopledosillythingsifinsillymoods'
同時(shí)想匹配如下模式:'sillymoods'
那么Perl正則表達(dá)式引擎匹配silly,接著遇到people的P,至此,Perl正則表達(dá)式引擎知道***個(gè)silly不匹配,于是Perl正則表達(dá)式引擎移到P且繼續(xù)尋求匹配。它接著遇到第二個(gè)silly,于是來匹配moods。然而得到的是字母t(在thing中),于是移到things中的t處,繼續(xù)進(jìn)行Perl正則表達(dá)式匹配。當(dāng)引擎遇到第三個(gè)silly并且盡力匹配moods時(shí),匹配成功,匹配***完成。當(dāng)我們遇到通配符時(shí)回溯將變得更加重要。如果在同一Perl正則表達(dá)式中有幾個(gè)通配符,且所有的通配符交織在一起,那么這里就有病態(tài)情形出現(xiàn),在這種情形下,回溯變得非常昂貴??慈缦卤磉_(dá)式:$line=m/expression.*matching.*could.*be.*very.*expensive.*/
◆*代表一個(gè)通配符,它意味著“匹配任意字符(換行符除外)零次或多次”。這個(gè)過程有可能花很長(zhǎng)時(shí)間;如果在未匹配過的字符串末尾有可能匹配,那么引擎將發(fā)狂地回溯。為得到這方面的更多信息,請(qǐng)留意關(guān)于通配符方面的原則。
如果讀者發(fā)現(xiàn)類似于上面的情形,那么通配符需將Perl正則表達(dá)式分解成小功部分。換句話講,簡(jiǎn)化自己的Perl正則表達(dá)式。
【編輯推薦】