


版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、word.word.word.word.1正則表達(dá)式有三種形式:匹配、替換和轉(zhuǎn)換。在表 9-1 中列有三種正則表達(dá)式運(yùn)算符。接下來(lái)對(duì)每一個(gè)表達(dá)式給出詳盡解釋。這種形式表明在/或 !的標(biāo)量。為了語(yǔ)法上的簡(jiǎn)化用/,m。這種形式表明正則表達(dá)式本 替換,為了語(yǔ)法的簡(jiǎn)化用/substituteTexts。tr/ 這種形式包含一系列的字符/同時(shí)把它們替換為。注意轉(zhuǎn)換據(jù)常使用它來(lái)進(jìn)行操縱。因此, tr/0-9/9876543210.1223456789987654321通過(guò)使用(用英語(yǔ)講:does,與“進(jìn)行匹配”同)和!(英語(yǔ):doesnt,與“不匹配”同)把這些表達(dá)式捆綁到標(biāo)量上。作為這種類(lèi)型的例子,下面
2、我們給出六個(gè)示例正則表達(dá)式及相應(yīng)的定義:$scalarName=s/a/b;#substitutethecharacteraforb,andreturnif this can happern$scalarName = m/a; # does the scalar $scalarName have an a in it?$scalarName=tr/A-Z/a-z/;#translateallcapitalletterwithlowerones, and return ture if this happens$scalarName!s/a/b/;#substitutethecharacteraf
3、orb,andreturnfalse if this indeed happens.$scalarName ! m/a/; # does the scalar $scalarName match the character a? Return false if it does.$scalarName!tr/0-9/a-j/;#translatethedigitsforthelettersathru j, and return false if this happens.如果我們輸入像 horned toad = m/toad/ 這樣的代碼,則出現(xiàn)圖 9-1 所示情況:另外,如果讀者正在對(duì)特定變
4、量 $_whilemapgrep!和=。因而,以下所有代碼都會(huì)合法:my elemente = ( al , a2 , a3 , a4 , a5 ); foreach (elements) s/a/b/;elementsb1,b2b3,b4,b5while() print if (m/ERBOR/);打印所有包含 error 字符串的行:if (grep(/pattern/, lines) print the variable lines has pattern in it!n;打印所有包含模式 pattern 內(nèi)容的行,這直接引入下一原則。2正則表達(dá)式僅在標(biāo)量上匹配。注意這里標(biāo)量的重要性,如
5、果讀者試一試如下代碼: arrayName = ( variablel, variable2);arrayName = m/variable/;# looks for variablein the array?No! grep instead那么arrayNamearrayNamePerl2,在輸入: 2 = m/variable/;至少講這不能給出預(yù)想的結(jié)果。如果讀者想這樣做,輸人為: grep(m/variable/, arrayName);該函數(shù)通過(guò)arrayName 中的每一個(gè)元素進(jìn)行循環(huán),返回(在標(biāo)量環(huán)境中)匹配的次數(shù),同時(shí)在數(shù)組環(huán)境中返回匹配元素的實(shí)際列表。3配或替換一次。小的可能
6、數(shù)量,這個(gè)數(shù)量的字符要保證不丟失任何匹配。PerlSilly people do silly things if in silly 同時(shí)想匹配如下模式:silly moodspeoplesillyPsilly,moods。然而得到的是字母 t(thingthingstsillymoods9-2 所示。當(dāng)我們遇到通配符時(shí)回溯將變得更加重要。如果在同一正則表達(dá)式中有幾個(gè)通配符,且所有的通配符交織在一起,那么這里就有病態(tài)情形出現(xiàn),在這種情形下, 回溯變得非常昂貴??慈缦卤磉_(dá)式: :$line = m/expression.*matching.*could.*be.*very.*expensive.*
7、/.* 代表一個(gè)通配符,它意味著“匹配任意字符(換行符除外)零次或多次”。這將發(fā)狂地回溯。為得到這方面的更多信息,請(qǐng)留意關(guān)于通配符方面的原則。如果讀者發(fā)現(xiàn)類(lèi)似于上面的情形,那么通配符需將正則表達(dá)式分解成小功部分。換句話講,簡(jiǎn)化自己的正則表達(dá)式。4正則表達(dá)式能夠處理雙引號(hào)字符串所能處理的任意和全部的字符。s/運(yùn)算符(s/*/),或者m/m/*/確實(shí)能像雙引號(hào)字符串一樣對(duì)待(帶有一些額外的附加功能,名義上的特殊正則表達(dá)式字符!后面描述)。讀者可用他們進(jìn)行內(nèi)插:$variable = TEST ; $a = m/$variableaha/; 和:$a = $variableaha ;二者都指向同一字
8、符串:前者在$aTESTaha后者把$aTESTaha執(zhí)行下列操作:$expression = hello;arrayName = ( elem1, elem2);$variable = m/$expression/; # this equals m/hello/;$expressionhellom/hello/可用于數(shù)組:$variable = m/arrayName/; # this equals m/elem1 elem2/;在這里,表達(dá)式等價(jià)于 m/elem1 elem2/。如果特殊變量$被設(shè)置為 |melem | elem2elemelem2。這種方法也可應(yīng)用于特殊字符:$varia
9、ble = m/x0127/; # match binary character x01, and # octal character 27.$variable = s/ttt/; # substitute three tabs for three spaces.m/中的過(guò)程的確像處理那么,如果想匹配類(lèi)似于正斜杠(/)或者園括引()這樣的字符會(huì)發(fā)生什么呢? 這些字符對(duì)正則表達(dá)式引取有特殊意義:因而不能使用如下語(yǔ)句:$variable m/usr/local/bin/; # matches /usr/local/bin? NO! SYNTAXERRORPerl/一包括反斜杠。因而剛才給出的例子可
10、變?yōu)椋?path = m/usr/local/bin/;該程序盡力匹配 $path 中的/usr/local/bin。第二種方法是使用一個(gè)不同的正則表達(dá)式字符。如果有許多字符要匹配,那么使用反斜杠則會(huì)變得很難看(路徑字符尤其不好)。m/s/ 時(shí)需要給每個(gè)/(/) $variable = m/usr/local/bin; # Note the quotation marks.$variable = mhelp; # If you are going to match quotation # marks, you need to backslash them here. (as per)$vari
11、able = S $variable $variable; # works in s/too.上是字符串的變相反插入;否則,引號(hào)就遠(yuǎn)不如斜杠常用。Perl 允許使用()來(lái)書(shū)寫(xiě)正則表達(dá)式:$variable=mthisworkswellwithvioremacsbecausetheparensbounce;$variable = m(this also works well);$variable = s(substitute pattern) for this patternsg;emacsvi第三種方法是利用函數(shù) quotemeta()來(lái)自動(dòng)地加反斜杠。如果輸入如下代碼:$variable =
12、 m $scalar;則$scalar都將被正則表達(dá)式引擎影響,并且可能引起語(yǔ)法錯(cuò)誤。因此,如果標(biāo)量為:$scalar = (; $variabie = m $scalar ;就等價(jià)于是說(shuō):$variable=m(為如下形式:$scalar = quotemeta( ();則表達(dá)式會(huì)使$scalar 變?yōu)?,且把$scalar 替換為:$variable = m ( ;這樣才可以匹配到讀者愿意匹配的字符串(。5正則表達(dá)式在求值的過(guò)程中產(chǎn)生兩種情況:結(jié)果狀態(tài)和反向引用。每次對(duì)正則表達(dá)式求值時(shí)會(huì)得到:指示正則表達(dá)式匹配字符串的次數(shù)(結(jié)果狀態(tài))。如果希望保存部分匹配,則有系列稱為反向引用的變量。接下
13、來(lái)讓我們依次學(xué)習(xí)他們:結(jié)果狀態(tài)求正則表達(dá)式的值。以下所有例子使用了這結(jié)果變量。$pattern = simple always simple;$result = ($pattern = msimple);這里,result1,simplesimple always simPle給定 simple always simple:$result = ($pattern = m complex);resultcomplexsimplealwayssimple$result = ($pattern = s simple complex);result1,simplecomplex$pattern = s
14、imple simple;$result = ($pattern = s simple complex g);simplealwayssimple出現(xiàn)兩次,同時(shí)正則表達(dá)式的 g 修飾符被使用,這意味著“匹配盡可能多的次數(shù)”。(要更詳細(xì)材料參看本章后面的修飾符)。同樣地:$pattern = simple still; if ($pattern = m simple)print MATCHED!n;if$pattern = m Perl,式$patternsimpleMatched! 。反向引用Perl一個(gè)運(yùn)算符(圓括號(hào)(),該運(yùn)算符可用于包圍讀者希望匹配的一系列給定的字符。在正則表達(dá)式中用圓括
15、號(hào)括住某模式就是告訴解釋器“嗨,我希望保存那個(gè)數(shù)據(jù)?!?Perl 解釋器再應(yīng)請(qǐng)求,且將查找到的匹配保存在一系列特珠的變量中求值而且進(jìn)行訪問(wèn)。例如:$text = this matches THIS not THAT ;$text = m (TH. ); print $1n;在這里,字柳 HIS 被打印出來(lái) Perl 已經(jīng)將它們保存在$1 中,以后再打印$1。 然而,該例子揭示了更多內(nèi)容,例如:THIS(TH.)然匹配THAT。THISregexp,THIS圖 9-3 表示了這一匹配過(guò)程如何進(jìn)行。在圖 9-3 中每個(gè)圓括號(hào)與自已的數(shù)字變量一道運(yùn)行。這里有更多的例子:$text = This is
16、 an example of backreferences;($example,$backreferences)=($text=(example).*(backreferences) );這里又用了通配符來(lái)分開(kāi)兩個(gè)文本字符串$example$backreferences$2$example$backrefercences94然而應(yīng)注意的是僅當(dāng)文本字符串匹配時(shí),給$example$bacbreferencebackreferencesif$1$2。if ($text = m (example).*(back)print $1; # prints example - since the first
17、 parens match the text example.print$2;# prints back -since thesecond parensmatch the textback這樣,如果正則表達(dá)式根本不匹配將發(fā)生什么?如果使用下面的模式:$text = This is an example of backreferences;$text = s (examplar).*(back) doesnt work; print $1;$1Perl有給$1backThis is an example of backreferences并不意味著整個(gè)表達(dá)式達(dá)到匹配。因?yàn)?exemplar 不在
18、字符串中,因而替換失敗。Perlgotcha。Perl過(guò),當(dāng)分析下面的代碼時(shí)第二點(diǎn)變得非常明顯。$a = bedbugs bite;$a = m (bedbug); # sets $1 to be bedbug.3$b = this is nasty;$b=m(nasti);#doesNOTset$1(nastiisnotinthisisnasty).# BUT $1 is still set to bedbug!print $1; # prints bedbug.在這種情況下,$1 為字符串 bedbug,因?yàn)榈?5 行的匹配失??!如果希望得到nastiPerl是自己要當(dāng)心。使用反向引用的一
19、般構(gòu)造法如果想避免這種很平常的缺陷(讀者想得到一個(gè)匹配,但是沒(méi)有得到并且用前面的匹配為 替代而結(jié)束),在把反向引用賦給變量時(shí)只要應(yīng)用下列三個(gè)構(gòu)造法之一:短路方法。核查匹配,如果匹配發(fā)生,此時(shí)且只有此時(shí)用 &如:($scalarName = m (nasti) ) $matched = $1;ififif式賦值。if ($scalarName = m (nasti) ) $matched = $1; else print $scalarName didnt match; ($match1, $match2) = ($scalarName = m (regexp1).*(regexp2) );的錯(cuò)
20、誤的話,那么這些形式將節(jié)省讀者的大量時(shí)間。在正則表達(dá)式中使用反向引用smPerls那么要使用語(yǔ)法$1,$2ms$string = far out;$string = s (far)(out) $2 $1; # This makes string out far. 我們?cè)谠摾兄皇菍卧~ far out 轉(zhuǎn)換為 out far。$string = sample examples;if ($string = m (amp.) ex1) print MATCHES!n; 這個(gè)例子有點(diǎn)復(fù)雜。第個(gè)模式(amp.)匹配字符串 ample。這意味轉(zhuǎn)整個(gè)模式ampleexample,其中帶下劃線的文本對(duì)應(yīng)于1
21、sample examples。下面是同樣風(fēng)格更復(fù)雜的例子;$string = bballball;$string = s (b)1(a.)12 $1$2;串的匹配有五個(gè)步驟:b1$11b,bb。3)(a.)匹配字符串 all 且被存在2 和$2 中。1b。因?yàn)?all(all)。將他們放到一起就得到正則表達(dá)式匹配 bballball,或者說(shuō)是整個(gè)字符串。既然$1 等于 b,$2 等于 all,則整個(gè)表達(dá)式:$string = bballball ;$string = s (b)1(a.)12 $1$2; (在這個(gè)例子中)轉(zhuǎn)換為如下代碼:$string = s (b)b(all)ball ba
22、ll;bballballball正則表達(dá)式看起來(lái)很像圖 9-5 所示。s 中有一些復(fù)雜的反向引用。如果理解了最后一個(gè)例子。那么讀者在理解Perl 的正則表達(dá)式如何工作方面遠(yuǎn)遠(yuǎn)走在了前面。反向引用可能而且確實(shí)會(huì)變得 更 糟 。 5進(jìn)行匹配的字符串作用明顯。例如下面的表達(dá)式:m (aaa)*) ;使用 * 來(lái)匹配多次出現(xiàn)的 aaa:即匹配,aaa,aaaaaa,aaaaaaaaa。換句話說(shuō), Perl3aaa的字符串:$string = softly slowly surely subtly;那么使用嵌套園括號(hào)后下面的正則表達(dá)式會(huì)匹配:$string = m (s.lys*)*) ; # note
23、 nested parens.在該例中,最外層的圓括號(hào)捕獲全部字符串:softly slowly surely subtlyslylysurely,將其拋開(kāi),然后捕獲 slowly, surely,subtly。這里有一個(gè)問(wèn)題,反向引用按在表達(dá)式中,一個(gè)反向引用越在前,它對(duì)應(yīng)的反向引用編號(hào)就越小。例如:$var = m (a)(b);該例中,反向引用(a)變?yōu)?1,(b)變成了$2。一個(gè)反向引用如果它包含范圍越廣,則它的反向引用編號(hào)就越小。例如:$var = m (c(a(b)*)*);該例中,包含全部?jī)?nèi)容(m(c(a(b)*)*)$1am(c(a(b)*)*)成為$2(m(c(a(b)*)*
24、)b成為$3。1$var = m (a)(b(c)(a)成為$1,b(c)成為$2,(c)成為$3。因而,在這個(gè)例子中,(s.lys*)*成為$1,(s.lys*)*成為$2。注意這里有另一個(gè)問(wèn)題。讓我們一起返回到剛開(kāi)始的復(fù)雜的正則表達(dá)式:$string = softly slowly surely subtly$string = m(s.lys*)*); # note nested parens.這里(s.lys*)*匹配什么呢?它匹配多個(gè)字符串;首先是softly,接著是再接著是最后是subtly既然(s.lys*)*匹配多個(gè)字符串那么Perl會(huì)拋棄掉第一個(gè)匹配而使$2成為subtly。P
25、erlPerl6PerlCPerl 正則表達(dá)式集合的強(qiáng)大功能來(lái)自于其匹配文本的多模式能力,(即:通過(guò)前面提到的邏輯“速記法”來(lái)描述許多不向的數(shù)據(jù)模式)。Perl通配符通配符代表字符類(lèi)。他沒(méi)有如下字符串,但不知道他們是否大寫(xiě):KumquatKristinaKentuckyKeyKeepingPerlKkPerl放在括號(hào)中最后加上結(jié)尾括號(hào)這種方法表示。前面的通配符告訴正則表達(dá)式引擎好,我正在這里查找K或者R。如果發(fā)現(xiàn)兩者之一那么就匹配它”。下面是另一些使用通配符的例于:$scalarName = this has a digit (1) in it;$scalarName = m 0-9; # T
26、his matches any character between 0 and 9, that is matches any digit.$scalarName = this has a capital letter (A) in it;$scalarName = m A-Z; # This matches any capital letter (A-Z).$scalarName = this does not match, since the letter after the string AN is an A$scalarName = m anA;thishasadigit(1)init1
27、this has acapital letter(A) in itA巧,因?yàn)樵谶@個(gè)模式中僅有一個(gè) an,所以可能被匹配的字符唯有最后的四個(gè)字an A。anA空格,最后一個(gè)為非 A 的字符。因而,該例中沒(méi)有完成匹配。如果給定模式為match an A not an an$scalarName = This has a tab( ) or a newline in it so it matches;$scalarName = m tn # Matches either a tab or a newline. # matches since the tab is present.字符串插入的相同字符
28、也可以在正則表達(dá)式和用括號(hào)表示的字符類(lèi)中(tn)入。其中t匹配制表符,n匹配換行符。其次如果讀者在里的開(kāi)頭部分放置一個(gè),則通配符會(huì)匹配非字符組中的字(A-Z)當(dāng)特別的通配符:$a = m a-fh-z; # matches any lowercaes letter * except* g.$a = m 0-9a-zA-Z; # matches any nonword character. (i.e.,NOT # a character in 0-9, a-z or A-Z)$a = m 0-9A-Za-z; # a mistake, Does not # equal the above. In
29、stead matches 0-9,$a = m tn; # matches a space character: tab, newline or blank).需許意的重要地方是第三個(gè)例子,在09AZaz中的插入記號(hào)是一個(gè)字面公用通配符須要輸入類(lèi)似于0-9們對(duì)應(yīng)的字符組合:d 匹配數(shù)字(字符組合0-9)。D 匹配非數(shù)(字符組合0-9)。w 匹配單詞字符 (字符組合a-zA-Z0-9_)(這里下劃線算作一個(gè)單詞字符)。W 匹配非單詞字符(字符組合a-zA-Z0-9_)。s 匹配空格字符(字符組合tn)(制表符、換行符、空格)。S 匹配非空格字符(字符組合tn)。nm(.*)S$- 盡管它實(shí)際上
30、并不是一個(gè)通配符(它不匹配任何具體字符)但它是廣泛使- 盡管實(shí)際上不是一個(gè)通配符,但如果它位于正則表達(dá)式的開(kāi)頭則它是匹配“行首”的特殊字符。零寬度斷言。 與$和(b)或匹配無(wú)單周邊(B)零寬度斷言。我們從表中注意到的第一點(diǎn)是“點(diǎn)”通配符(.)。它常與多重匹配運(yùn)算符一道用于在條目間充當(dāng)填充者。請(qǐng)看以下匹配:$a=NOWisthetimeforallgoodmentocometotheaidoftheirparty;$a = m (Now).*(party); # matches, since . matches any character except newlineand * means ma
31、tch zero or more characters.*Nowparty們后面談到多重匹配運(yùn)算時(shí)再談它。)下面是通配符的一些其他例子。注意我們?cè)?的左邊使用了單引用字符串(這是一個(gè)測(cè)試表達(dá)式的簡(jiǎn)單方法):1 1956.23 = m (d+).(d+); # $1 = 1956, $2 = 232 333e+12 = m (D+); # $1 = e+3 $hash($value) = m $(w+)$(w+); # $1 = hash, $2 = value4 $hash($value) = m $(w+)(w)*(w+)(w*); # $1 = $, $2 = hash,# $3 = $,
32、 $4 = value5VARIABLE=VALUE=m(w+)(s*)=(s*)(w+);#$1=VARIABLE, #$2 = ,# $3 = , $4 = VALUE catch as catch can = m (.*)can$; # $1 = catch as catch can as catch catch = mcan(.*)$ # $1 = as catch catchword_with_underlinesword2=mb(w+)b;#$1word_with_underlines每個(gè)例子中,我們使用了一個(gè)不同的通配符,在該程序中,用*表示在“一行中匹配零個(gè)或者多個(gè)通配符”。用
33、+表示“在一行中匹配一個(gè)或者多個(gè)通配符”。5s*84哈希結(jié)構(gòu)的一般化方法。1PerlPerl們?cè)谙旅嬷v述侖們。零寬度斷言和正寬度斷言在表 9-2 中的字符就是讀者可能稱作的正寬度斷言:表 9-2 正聲明D 非數(shù)字dwW 非單詞s 空格S 非空格則表達(dá)式引擎在匹配過(guò)程中“吃掉”它們。在表 9-3 中列出的負(fù)寬度斷言。這些斷言不是匹配一個(gè)字符,它們匹配的是一種條件。換句話講,cat 匹配以cat 開(kāi)頭的字符串,但并不匹配任一給定字符。請(qǐng)看下面的表達(dá)式:$ziggurautString = this matches the word zigguraut;$ziggurautString = m bz
34、iggurautb;$ziggurautString = m WziggurautW;第一個(gè)例子匹配成功,因?yàn)樗窃趦蓚€(gè)非單詞字符(單詞邊界)之間查ziggurat。而字符串滿足這種條件。W須匹配一個(gè)字符。但是在行未不是字符,而是一種條件。這是重要的區(qū)別。到的字符。因此,如果輸入如下代碼:$ziggurautString = This matches the word zigguraut now;$ziggurautString = s WziggurautW g;最后得到的結(jié)果是 This matches the wordnow。原因是已經(jīng)把單詞和插入的空格替換掉了。因而:零寬度斷言,例如b
35、B 能匹配沒(méi)有字符的地方。它們?cè)谄ヅ涞倪^(guò)程中不會(huì)去掉任一字符。下面是關(guān)于通配符匹配的其他例子:$example = 111119;$example=mddd;#matchthefirstthreedigitsitcanfindinthe string Matches 111.$example = This is a set of words and not of numbers;$example = m of (wwwww); # Matches of words .Createsbackreference請(qǐng)注意最后一個(gè)例子,該列中,因?yàn)樵谧址拈_(kāi)頭有一個(gè)of(wordsofof(在 num
36、bersPerl多重匹配運(yùn)算符PerI 中有六個(gè)多重匹配運(yùn)算符。主要用于避免編寫(xiě)重復(fù)代碼,例如上一節(jié)提到的在一行中聲明w 五次。瀆者可把它們看作是速記的捷徑。PerI 的六個(gè)多重匹配運(yùn)算符是:*匹配零次,一次或多次。 ?匹配一次或者多次。?匹配零次或者一次。X匹配X次。X或者更多次。匹配X到Y(jié)次。這里有兩個(gè)等價(jià)的例子,但是哪個(gè)易讀呢?$example= Thisis a set of words and not of numbers;$example= m of(wwwww); # Matches of word.$example= m of(w5); # Usage of X form. M
37、atches5 characters,# and backreference $1 becomes the string words.aaa,aa,$example = this matches a set of words and not of numbers;$example = m of(w+);匹配的是字符串 words(of(w+) eq of words),又如:$example=mof(w(2,3); #UsageofX,Y. Matchesthestring# (the first three letters of the first match it finds.matche
38、s the string wor ( of w2,3 equals of wor here) 與直覺(jué)相反下面代碼中的 m 子句:$example = this matches a set of words and not of numbers;$example = m of(d*);d*d*個(gè)到多個(gè),所以表達(dá)式匹配零個(gè)數(shù)字!然而:$example = m of(d+);d+而不是d*of有的。貪婪達(dá)式匹配給定的字符串。即缺省情況下,多重匹配運(yùn)算符是貪婪地。運(yùn)算符能捕獲一個(gè)字符串中的最大數(shù)量的字符,同的仍然有能力來(lái)完成模式匹Perl以免跟蹤古怪的正則表達(dá)式行為。我們從下面的語(yǔ)句開(kāi)始:$examp
39、leThisisthebestexampleofthegreedypatternmatchinPerl5; is。相應(yīng)地,要編寫(xiě)如下代碼:$example = m # This (.*) the#;print $1; # This does NOT print out the string is!讀者希望打印$1is is the best example of程序的工作過(guò)程如圖 9-6 所示。造成這種結(jié)果的原因是多重匹配運(yùn)算符*the(greedy則表達(dá)式后得到不可預(yù)料結(jié)果。這里有更多例子:$example = sam I am;$example = m (.*)am; # matches
40、the string sam I$example = RECORD: 1 VALUE: A VALUE2: B;$example = m.RECORD;(.*)VALUE; # matches 1 VALUE: A;$example = RECORD;$example = m w2,3; # matches RECRECORDPerIRE=w2,3,則只能匹配兩個(gè)字符,因?yàn)檫@是可能匹配的最大數(shù)量。4回溯和多重通配符好吧,已經(jīng)準(zhǔn)備很久了現(xiàn)在到處理棘手題目的時(shí)候了。正如前面說(shuō)過(guò)的,通配符和回溯的結(jié)合使正則表達(dá)式有極其緩慢的性能。如果讀者理解了其中的原因, 那么這是讀者正“得到” 正則表達(dá)式的好標(biāo)志
41、??匆韵吕樱?string = m has(.*)multiple(.*)wildcards; 這意味著正則表達(dá)式將查找(以數(shù)字順序):has(m has.*multiple.*wildcards)。正則表達(dá)式能發(fā)現(xiàn)的最大文本直到它到達(dá)最后的has(.*)mMltiple(.*)wildcards)。multiple(m has(.*)multiple(.*)wildcards)。能發(fā)現(xiàn) 的 最大文本 直 到遇到最 后 的has(.*)multiple(.*)wildcards)。wildcards(m has(.*)multiple(.*)wildcards接著考慮一下,使用以下的模式將會(huì)
42、發(fā)生什么:has many multiple wildcards multiple WILDCARDS所發(fā)生的一切是:、Perlhas(i.e,mhas(.*)multiple(.*)wildcards); has many multiple wildcards multiple WILDCARDSPerlm has(.*)multiple(.*)wildcardsmultiple,接著匹配:has many multipIe wildcards multiple WILDCARDSPerlmultiple(mhas(.*)multiple(.*)wildcards): has many mu
43、ltiple wildcards multiple WILDCARDSPerlwildcardsWILDCARDS does not match wildcards !Perl(*),Perl2has many multiple wildcards multiple WILDCARDS 時(shí),因而,它正好返回到 has 后面:has many multiple wildcards multiple WILDCARDSgoes back heremultiplemhas(.*)multiple(.*)wildcards 匹配:has many multiple wildcards multiple
44、 WILDCARDSm has(.*)multiple(.*)wildcardsmultiplehas many multiple wildcards multiple WILDCARDS接著通配符匹配空格m has(.*)multiple(.*)wildcards)匹配:has many multiple wildcards multiple WILDCARDS最后,wildcards(m has(.*)multiple(.*)wildcardshas many multiple wildcards multiple WILDCARDShas many multiple wildcards但
45、是得到該結(jié)果肯定走了彎路??隙ǖ卣f(shuō),Perl 實(shí)施正則表達(dá)式的算法有些捷PerlPerl代碼:$pattern = afbgchdjafbgche;$pattern = m a(.*)b(.*)c(.*)d; 我們?cè)诖穗S意結(jié)出一個(gè):afbgchdjafbgcheafbgchdjafbgche(m(ma(.*)b(.*)c(.*)d;)a(.*)b(.*)c(.*)d;)-greedy, goes to last bafbgchdjafbgche(ma(.*)b(.*)c(.*)d;)afbgchdjafbgche(ma(.*)b(.*)c(.*)d;)-matches gafbgchdjafb
46、gche(ma(.*)b(.*)c(.*)d;)afbgchdjafbgche(ma(.*)b(.*)c(.*)d;)-backtrack because no dafbgchdjafbgche(ma(.*)b(.*)c(.*)d;)-now we take up everything tothe next to last bafbgchdjafbgche(ma(.*)b(.*)c(.*)d;)afbgchdjafbgche(ma(.*)b(.*)c(.*)d;)-now the second .* becomesgreedy.afbgchdjafbgche(ma(.*)b(.*)c(.*)d
47、;)afbgchdjafbgche(ma(.*)b(.*)c(.*)d;)-still no d.darn.backtracksafbgchdjafbgche(ma(.*)b(.*)c(.*)d;)-wildcardbecomeslessgobbles to next to last cafbgchdjafbgche (m a(.*)b(.*)c(.*)d;)afbgchdjafbgche (m a(.*)b(.*)c(.*)d;) - there is only one d in the expression and this matches up to itafbgchdjafbgche
48、(m a(.*)b(.*)c(.*)d;) - a match! matches afbgchd.配運(yùn)算優(yōu)先于右邊的執(zhí)行。下面這樣的模式:m (.*)(.*);-Dr- Dr.script.p21處理字符的非貪婪形式。5非貪婪多重匹配運(yùn)算符CFAQ/* this is a comment*/ /* another comment */這里試圖找出一個(gè)貪婪方式的解決方法。我們想匹配后跟所有文本的/* 直到包括 */。如果我們嘗試以下代碼:m /*.*/; 于是,將匹配:/* this is a comment*/ /* another comment */ 又一次因?yàn)槭?greedy 形式所以匹
49、配全部字符串。以$commentmatcher = m /*(*|*/*)*/;m我們它們:只要在一個(gè)貪婪多重運(yùn)算符的后面添加?就可使之成為非貪婪。因而,前面的 commentmatcher 成為:$commentmatcher = m /*(.*?)*/;所示。“懶惰”是用于描述?的另一術(shù)語(yǔ)。正則表達(dá)式引擎可以北認(rèn)為是緩慢地前移, */驟。如果讀者輸入以下代碼:$line = m (.*?)(.*?)(.*?);每個(gè)(.*?)符什么也不會(huì)匹配。什么原因呢 ?在這里匹配的最小數(shù)量的字符是零(因?yàn)樽x者已經(jīng)輸入*(.*?) d就可得到懶惰行為:*?匹配零、一或多次,但匹配可能的最少次數(shù)。+?匹配一
50、或多次,但匹配可能的最少次數(shù)。?匹配零次或一次,仍匹配可能的最少次數(shù)。X?正好匹配“X”次X, ?匹配“X”或者更多次,但匹配可能的最少次數(shù)。X,Y?匹配“X”到“Y”次,但匹配可能的最少次數(shù)。這里有關(guān)于最小匹配程序的一些例子,以及那些與非貪婪模式匹配的例子:$example = This is the time for a11good man to come to of their party ;$example = m This (.*?) the;isisthetimeforallgoodto come to。$example = 19992113333333333333331;if (
51、$example = m l (d3,?) )該表達(dá)式表示匹配后跟三個(gè)數(shù)(或更多數(shù)字)的l1。因此,將匹配到1999。$example = 1f999133333333333333331;if ($example = m l (d3,?) )1f1,1333。$example = 1f999133333333333333331;if ($example = m l (d3,?)1 )d(3,)到什么數(shù)據(jù)字1PerlPerl7Perl替換Per1(able | baker | charlie)Per1ablebakercharlie子,以下面的語(yǔ)句開(kāi)始:$declaration=charstri
52、ng80;or$declaration=unsignedstring 80;charunsigned char,的。下面的正則表達(dá)式二者都匹配:foreach $declaration ( char string 80, unsigned char string 80 )if ($declaration = m (unsigned char | char ) )print :$1: ; # prints :char : first timearound.# prints :unsigned char : second timearound .語(yǔ)法 | 意味著匹配 unsigned char 或
53、者 char 且把已 匹配的字符串保存在反向引用中。替換可以是很微妙的,因?yàn)閷?duì)于替換行為有一件重要的事情要記?。菏降钠ヅ洌来晤?lèi)推。前面的例子來(lái)說(shuō),假定改變了圓括號(hào)中條目的次序,那么該例子變?yōu)椋?declaration = unsigned char string 80;$declaration = m (char | unsigned char );unsigned char (unsigned char string 80cha(unsignedcharstring80charunsigned charchar,因而在反向引用中保存了錯(cuò)誤的替換。這種錯(cuò)誤信息很普通,所以這里指出一點(diǎn):這么做,則會(huì)陷入痛苦的等待中,例如:$line = m (. * | word );word。這是因?yàn)閣ord也就是四個(gè)任一字符)時(shí)正則表達(dá)式極左匹配,所以首先拾取.*,因而:$line = wordstar;
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 內(nèi)控審計(jì)合同范本
- 仁和經(jīng)銷(xiāo)合同范本
- 加盟返利合同范本
- 代購(gòu)代理合同范本
- 農(nóng)村建房簽合同范本
- 共同合作居間合同范本
- 化學(xué)桶回收合同范本
- it行業(yè)采購(gòu)合同范本
- 分戶協(xié)議合同范本
- 勞動(dòng)合同正規(guī)合同范本
- (完整版)ERP流程及操作手冊(cè)
- 接上童氣:小學(xué)《道德與法治》統(tǒng)編教材研究
- 武器講解課件
- 通勤車(chē)租賃投標(biāo)方案(技術(shù)標(biāo))
- 關(guān)于魯迅簡(jiǎn)介
- 余華讀書(shū)分享名著導(dǎo)讀《文城》
- 植物組織培養(yǎng)(園林植物教研組)-說(shuō)課稿
- 高三二輪專題復(fù)習(xí)化學(xué)課件-分布系數(shù)(分?jǐn)?shù))圖像
- 支委委員辭去職務(wù)申請(qǐng)書(shū)
- 【橋梁工程的發(fā)展趨勢(shì)與思考5300字】
- 云南省蒙自市長(zhǎng)橋海水庫(kù)擴(kuò)建工程環(huán)評(píng)報(bào)告
評(píng)論
0/150
提交評(píng)論