国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

正則表達式入門教程(三)

2019-11-11 02:57:17
字體:
來源:轉載
供稿:網友

這篇是正則表達式的第三篇,我們接著第二篇的知識點開始講:

一:反義

有時需要查找不屬于某個能簡單定義的字符類的字符。比如想查找除了數字以外,其它任意字符都行的情況,這時需要用到反義:

表中上面四個字母都是大寫:/W , /S , /D , /B

例子:/S+匹配不包含空白符的字符串。

<a[^>]+>匹配用尖括號括起來的以a開頭且以>結尾的字符串,a和>中間不能有>。

解析:<a> 表示以<和a開頭,以>結尾 ;[^>]+ 表示 a 和>中間不可以是>,且至少有一個或更多的字符

強化理解:

^的用法:

(1)

^表示表達式驗證的開始,要驗證的字符串完整的匹配^后面的內容。比如: ^567     匹配“567”+str; $ 表示表達式驗證的結束,要驗證的字符串完整的匹配$前面的內容。 比如 567$       匹配str+"567";^$結合起來   比如 ^567$              匹配 567;

(2)

 ^的另一種語意識非              比如 ^[^567]*$        匹配的字符串不包含5、6、7任意字符解釋: ^開始了一個字符串的匹配,[]表示定義需要匹配內容的一個小節點的自定義,可以是很簡單的[5],或者復雜點的[a-z]的小寫字母或者[a-zA-Z]的字母限定。這里的[^567]就表示你定義的這個節點的內容不能是5、6、7中的任意一個。最后$表示字符串的匹配結束,你的字符串不能包括多余以^開頭以$結尾的內容。

二:反向引用

使用小括號指定一個子表達式后,匹配這個子表達式的文本(也就是此分組捕獲的內容)可以在表達式或其它程序中作進一步的處理。默認情況下,每個分組會自動擁有一個組號,規則是:從左向右,以分組的左括號為標志,第一個出現的分組的組號為1,第二個為2,以此類推。

呃……其實,組號分配還不像我剛說得那么簡單:

分組0對應整個正則表達式

實際上組號分配過程是要從左向右掃描兩遍的:第一遍只給未命名組分配,第二遍只給命名組分配--因此所有命名組的組號都大于未命名的組號

你可以使用(?:exp)這樣的語法來剝奪一個分組對組號分配的參與權.

后向引用用于重復搜索前面某個分組匹配的文本。例如,/1代表分組1匹配的文本。難以理解?請看示例:

/b(/w+)/b/s+/1/b可以用來匹配重復的單詞,像go go, 或者kitty kitty。這個表達式首先是一個單詞,也就是單詞開始處和結束處之間的多于一個的字母或數字(/b(/w+)/b),這個單詞會被捕獲到編號為1的分組中,然后是1個或幾個空白符(/s+),最后是分組1中捕獲的內容(也就是前面匹配的那個單詞)(/1)。

你也可以自己指定子表達式的組名。要指定一個子表達式的組名,請使用這樣的語法:(?<Word>/w+)(或者把尖括號換成'也行:(?'Word'/w+)),這樣就把/w+的組名指定為Word了。要反向引用這個分組捕獲的內容,你可以使用/k<Word>,所以上一個例子也可以寫成這樣:/b(?<Word>/w+)/b/s+/k<Word>/b。

使用小括號的時候,還有很多特定用途的語法。下面列出了最常用的一些:

我們已經討論了前兩種語法。第三個(?:exp)不會改變正則表達式的處理方式,只是這樣的組匹配的內容不會像前兩種那樣被捕獲到某個組里面,也不會擁有組號。

反向引用這部分有點難,后面慢慢理解吧

三、零寬斷言

       表4中,接下來的四個用于查找在某些內容(但并不包括這些內容)之前或之后的東西,也就是說它們像/b,^,$那樣用于指定一個位置,這個位置應該滿足一定的條件(即斷言),因此它們也被稱為零寬斷言。最好還是拿例子來說明吧:

斷言用來聲明一個應該為真的事實。正則表達式中只有當斷言為真時才會繼續進行匹配。

       (?=exp)   也叫零寬度正預測先行斷言,它斷言自身出現的位置的后面能匹配表達式exp。

比如/b/w+(?=ing/b),匹配以ing結尾的單詞的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.時,它會匹配sing和danc。

(?<=exp)也叫零寬度正回顧后發斷言,它斷言自身出現的位置的前面能匹配表達式exp。

比如(?<=/bre)/w+/b會匹配以re開頭的單詞的后半部分(除了re以外的部分),例如在查找reading a book時,它匹配ading。

假如你想要給一個很長的數字中每三位間加一個逗號(當然是從右邊加起了),你可以這樣查找需要在前面和里面添加逗號的部分:((?<=/d)/d{3})+/b,用它對1234567890進行查找時結果是234567890。

下面這個例子同時使用了這兩種斷言:(?<=/s)/d+(?=/s)匹配以空白符間隔的數字(再次強調,不包括這些空白符)

四、負向零寬斷言

前面我們提到過怎么查找不是某個字符或不在某個字符類里的字符的方法(反義)。但是如果我們只是想要確保某個字符沒有出現,但并不想去匹配它時怎么辦?例如,如果我們想查找這樣的單詞--它里面出現了字母q,但是q后面跟的不是字母u,我們可以嘗試這樣:

/b/w*q[^u]/w*/b匹配包含后面不是字母u的字母q的單詞

但是如果多做測試(或者你思維足夠敏銳,直接就觀察出來了),你會發現,如果q出現在單詞的結尾的話,像Iraq,Benq,這個表達式就會出錯。

這是因為[^u]總要匹配一個字符,所以如果q是單詞的最后一個字符的話,后面的[^u]將會匹配q后面的單詞分隔符(可能是空格,或者是句號或其它的什么),后面的/w*/b將會匹配下一個單詞,于是/b/w*q[^u]/w*/b就能匹配整個Iraq fighting。

負向零寬斷言能解決這樣的問題,因為它只匹配一個位置,并不消費任何字符。現在,我們可以這樣來解決這個問題:/b/w*q(?!u)/w*/b。

零寬度負預測先行斷言(?!exp),斷言此位置的后面不能匹配表達式exp。例如:/d{3}(?!/d)匹配三位數字,而且這三位數字的后面不能是數字;/b((?!abc)/w)+/b匹配不包含連續字符串abc的單詞。

同理,我們可以用(?<!exp),零寬度負回顧后發斷言來斷言此位置的前面不能匹配表達式exp:(?<![a-z])/d{7}匹配前面不是小寫字母的七位數字。

一個更復雜的例子:(?<=<(/w+)>).*(?=<///1>)匹配不包含屬性的簡單HTML標簽內里的內容。(?<=<(/w+)>)指定了這樣的前綴:被尖括號括起來的單詞(比如可能是<b>),然后是.*(任意的字符串),最后是一個后綴(?=<///1>)。注意后綴里的//,它用到了前面提過的字符轉義;/1則是一個反向引用,引用的正是捕獲的第一組,前面的(/w+)匹配的內容,這樣如果前綴實際上是<b>的話,后綴就是</b>了。整個表達式匹配的是<b>和</b>之間的內容(再次提醒,不包括前綴和后綴本身)。

請詳細分析表達式(?<=<(/w+)>).*(?=<///1>),這個表達式最能表現零寬斷言的真正用途。

五、注釋

小括號的另一種用途是通過語法(?#comment)來包含注釋。例如:2[0-4]/d(?#200-249)|25[0-5](?#250-255)|[01]?/d/d?(?#0-199)。

要包含注釋的話,最好是啟用“忽略模式里的空白符”選項,這樣在編寫表達式時能任意的添加空格,Tab,換行,而實際使用時這些都將被忽略。啟用這個選項后,在#后面到這一行結束的所有文本都將被當成注釋忽略掉。例如,我們可以前面的一個表達式寫成這樣:

      (?<=    # 斷言要匹配的文本的前綴      <(/w+)> # 查找尖括號括起來的字母或數字(即HTML/xml標簽)      )       # 前綴結束      .*      # 匹配任意文本      (?=     # 斷言要匹配的文本的后綴      <///1>  # 查找尖括號括起來的內容:前面是一個"/",后面是先前捕獲的標簽      )       # 后綴結束

參考博客:http://deerchao.net/tutorials/regex/regex.htm#mission


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 措美县| 名山县| 饶河县| 屯昌县| 互助| 舟山市| 化隆| 江川县| 鄢陵县| 海盐县| 古丈县| 寿阳县| 鄂州市| 庆阳市| 怀安县| 天气| 青河县| 宜城市| 万荣县| 伊吾县| 前郭尔| 太白县| 西充县| 龙泉市| 宿州市| 土默特左旗| 甘洛县| 巴林右旗| 昌吉市| 依兰县| 德格县| 宜昌市| 来宾市| 新津县| 凤冈县| 温州市| 河池市| 龙川县| 锡林郭勒盟| 澜沧| 繁昌县|