国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

php實戰(zhàn)正則表達式(二):提取html元素

ityouknow / 1062人閱讀

摘要:在閱讀這篇文章前最好把同系列文章實戰(zhàn)正則表達式一驗證手機號先仔細閱讀一遍。但實際上這樣一個表達式是無法從上面的中提取第一個元素的這里主要的問題是在默認情況下點號字符無法匹配換行符。但是很遺憾,正則表達式中沒有排除型子表達式或者說排除型分組。

這篇文章通過提取html元素介紹了正則表達式中模式修飾符貪婪匹配非貪婪匹配Unicode模式環(huán)視等知識點。
在閱讀這篇文章前最好把同系列文章php實戰(zhàn)正則表達式(一):驗證手機號先仔細閱讀一遍。

基本提取

有這樣一個表格

用戶名 職業(yè)
Kobe Bryant 籃球運動員
Jay Chou 歌手、詞曲創(chuàng)作人、制作人、演員、導演
Lionel Messi 足球運動員

它的源碼如下:

用戶名職業(yè)
Kobe Bryant籃球運動員
Jay Chou歌手、詞曲創(chuàng)作人、制作人、演員、導演
Lionel Messi足球運動員

現(xiàn)在要提取第一個元素。最簡單的正則表達式應該是這樣:

s+.*

其中

s是php實戰(zhàn)正則表達式(一):驗證手機號介紹過的字符組簡記法中的一個,代表回車符、空格、制表符等空白字符

量詞+表示它所修飾的字符或字符組出現(xiàn)次數(shù)大于等于1

點號字符.在正則表達式中是一個特殊的元字符,它可以匹配“任意字符”

閉標簽中的斜線/在php的正則表達式中是模式分隔符,所以需要轉義來表示斜線字符。

但實際上這樣一個表達式是無法從上面的中提取第一個元素的

這里主要的問題是在默認情況下點號字符.無法匹配換行符 。有兩個方法可以解決這個問題:

使用模式修飾符s,正則表達式為/s+.*/s(?s)s+.*。模式修飾符s的作用就是讓點號字符.可以匹配換行符。

[sS][wW][dD]代替點號字符.來匹配所有字符,正則表達式為s+[sS]*

關于模式修飾符(Pattern Modifiers),這里需要詳細介紹一下(點擊這里查看php支持的所有模式修飾符)。模式修飾符可以改變正則表達式的一些默認規(guī)則,常用的模式修飾符有i、s、U、u等,我們在后面會用到它們中的一些,這里不展開介紹每個模式修飾符的作用,后面用到了再具體介紹。這里主要對比一下/.../{modifier}與...(?{modifier})...兩種表示方法的區(qū)別。

.*/s(?s).*
模式修飾符 /.../{modifier} ...(?{modifier})...
示例 /
名稱(php手冊) 模式修飾符 模式內修飾符
名稱(《正則指引》) 預定義常量 模式修飾符
作用范圍 整個正則表達式 不在分組(子表達式)中時,對它后面的全部正則表達式起作用;如果在分組(子表達式)中,則對它分組中的剩余部分起作用。在沒有分組,且放在整個正則表達式最前面的時候相當于/.../{modifier}
支持程度 支持所有模式修飾符 支持部分模式修飾符
其他編程語言 可能不支持 一般都支持

從上面的gif中可以看到提取的結果中有三個tr,而不是只有一個。這是因為正則表達式中量詞默認是貪婪匹配,在這里,.*會匹配一切字符,直到最后沒有字符再向前回溯,回溯到中的最后一個時與正則表達式中的相匹配,從而完成整個匹配過程,最后的結果也就是包含了三個

可以使用模式修飾符U指定整個正則表達式為非貪婪模式,也可以使用非貪婪匹配量詞指定某一個量詞為非貪婪模式:

指定整個正則表達式為非貪婪模式:

/s+.*/Us

(?Us)s+.*

非貪婪量詞:
/s+.*?/s

完整的貪婪量詞(匹配優(yōu)先量詞)與非貪婪量詞(忽略優(yōu)先量詞)見下表:

貪婪量詞 非貪婪量詞 限定次數(shù)
* *? 可能出現(xiàn),可能不出現(xiàn),出現(xiàn)次數(shù)沒有上限
+ +? 至少出現(xiàn)1次,沒有上限
? ?? 出現(xiàn)0次或1次
{m,n} {m,n}? 出現(xiàn)次數(shù)大于等于m,小于等于n
{m,} {m,}? 至少出現(xiàn)m次,沒有上限
{0,n} {0,n}? 出現(xiàn)0次-n次
提取包含指定內容的行

假設我們想把表格中有關于運動員的記錄都提取出來,我們可能會使用/.*運動員.*/s這樣的正則表達式。

這個表達式在Unicode編碼環(huán)境下可以匹配出結果,但是在GBK環(huán)境下就未必了。我們可以通過模式修飾符u來指定Unicode模式:

/.*運動員.*/us

在Unicode模式下,我們甚至可以使用碼值來代替漢字:

/.*x{8fd0}x{52a8}x{5458}.*/us

php正則中使用x{hex}的形式來表示Unicode字符的碼值,使用碼值的好處是可以結合字符組來表示一段范圍,如[x{4e00}-x{9fff}]表示匹配所有漢字字符。

上面的表達式可以匹配出結果,但是卻不正確。我們可以看到,它匹配了整個字符串的第一個到最后一個
直覺上,我們是想正則表達式先去匹配“運動員”,然后向左尋找最近的一個,向右尋找最近的一個。但事實上,正則表達式是從左往右匹配的,即從開始尋找,整個正則表達式的匹配情況見下表(空白字符沒有顯示出來)。

表達式 匹配值
/
.* 用戶名職業(yè)
Kobe Bryant籃球
運動員 運動員
.*
Jay Chou歌手、詞曲創(chuàng)作人、制作人、演員、導演
Lionel Messi足球運動員
/us

這里兩個.*匹配到的字符都比預期要多。第二個.*匹配字符比預期多的原因是正則表達式默認是貪婪匹配模式,它會匹配剩余字符串中的每個字符,直到字符串的末尾,然后再向前回溯到最后一個,可以通過指定非貪婪匹配模式來解決這個問題。但是第一個.*匹配字符比預期多是正常現(xiàn)象,因為正則表達式是從左向右匹配的,表達式中的匹配字符串中第一個,后面的.*則匹配剩余的所有字符,直到字符串的末尾,然后再向前回溯到“運動員”。

我們先看看使用非貪婪匹配時的結果:

可以看到,第二個.*匹配的字符已經(jīng)是我們想要的了。那么,對于第一個.*匹配字符比預期多這個問題怎么解決呢?

如果僅使用到目前為止我的文章中介紹的知識,也是有方法可以解決的。我們可以先從左到右匹配出所有的行(...),方法是使用php中的preg_match_all函數(shù)結合非貪婪匹配模式;然后再遍歷每一行,過濾出其中包含“運動員”的行即可。

當然,我們也可以通過純粹的正則表達式來解決這個問題。如果有一定正則表達式使用經(jīng)驗的朋友可能很容易聯(lián)想到排除型字符組,我們介紹過字符組[...],它表示在同一位置可能出現(xiàn)的字符。而排除型字符組則表示在同一位置不能出現(xiàn)的字符,它的形式是[^...],通過緊跟在開方括號[后面的^來表示排除型字符組。例如,[^d]表示匹配的字符是除了數(shù)字以外的任意字符。
如果有排除型子表達式,類似于(^)*,我們只需要指定第一個.*排除就行了。但是很遺憾,正則表達式中沒有排除型子表達式或者說排除型分組。這種情況下,我們只能使用環(huán)視

/(.(?!))*運動員.*/Us

環(huán)視(look-around)不匹配任何字符,用來“停在原地,四處張望”。上面的表達式使用了否定順序環(huán)視,它的形式是(?!...)。具體對于(.(?!))*來分析,每當.匹配了一個字符后,就向右看看,如果當前匹配字符的右邊沒有出現(xiàn)就匹配成功。

完整的環(huán)視有:

名字 記法 含義
肯定順序環(huán)視 (?=...) 向右看看,右邊出現(xiàn)了環(huán)視中的內容才匹配
否定順序環(huán)視 (?!...) 向右看看,右邊不出現(xiàn)環(huán)視中的內容才匹配
肯定逆序環(huán)視 (?<=...) 向左看看,左邊出現(xiàn)了環(huán)視中的內容才匹配
否定逆序環(huán)視 (? 向左看看,左邊不出現(xiàn)環(huán)視中的內容才匹配

由于上面的正則表達式有一個分組(子表達式),所以匹配的結果除了下標0,還有下標1,這里下標1的結果其實沒有什么用,我們可以用之前介紹過的非捕獲分組

/(?:.(?!))*運動員.*/Us

我們的真正目的是提取所有包含“運動員”的行,而上面只提取了第一個,所以需要將preg_match函數(shù)換成preg_match_all

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/21126.html

相關文章

  • Python3網(wǎng)絡爬蟲實戰(zhàn)---26、正則達式

    摘要:上一篇文章網(wǎng)絡爬蟲實戰(zhàn)高級用法下一篇文章網(wǎng)絡爬蟲實戰(zhàn)與正則表達式抓取貓眼電影排行本節(jié)我們看一下正則表達式的相關用法,正則表達式是處理字符串的強大的工具,它有自己特定的語法結構,有了它,實現(xiàn)字符串的檢索替換匹配驗證都不在話下。 上一篇文章:Python3網(wǎng)絡爬蟲實戰(zhàn)---25、requests:高級用法下一篇文章:Python3網(wǎng)絡爬蟲實戰(zhàn)---27、Requests與正則表達式抓取貓眼...

    Pocher 評論0 收藏0
  • Python3網(wǎng)絡爬蟲實戰(zhàn)---28、解析庫的使用:XPath

    摘要:上一篇文章網(wǎng)絡爬蟲實戰(zhàn)與正則表達式抓取貓眼電影排行下一篇文章網(wǎng)絡爬蟲實戰(zhàn)解析庫的使用上一節(jié)我們實現(xiàn)了一個最基本的爬蟲,但提取頁面信息時我們使用的是正則表達式,用過之后我們會發(fā)現(xiàn)構造一個正則表達式還是比較的繁瑣的,而且萬一有一點地 上一篇文章:Python3網(wǎng)絡爬蟲實戰(zhàn)---27、Requests與正則表達式抓取貓眼電影排行下一篇文章:Python3網(wǎng)絡爬蟲實戰(zhàn)---29、解析庫的使用:...

    abson 評論0 收藏0
  • Python3網(wǎng)絡爬蟲實戰(zhàn)---27、Requests與正則達式抓取貓眼電影排行

    摘要:所以我們如果想獲取電影,只需要分開請求次,而次的參數(shù)設置為,,,,即可,這樣我們獲取不同的頁面結果之后再用正則表達式提取出相關信息就可以得到的所有電影信息了。上一篇文章網(wǎng)絡爬蟲實戰(zhàn)正則表達式下一篇文章網(wǎng)絡爬蟲實戰(zhàn)解析庫的使用 上一篇文章:Python3網(wǎng)絡爬蟲實戰(zhàn)---26、正則表達式下一篇文章:Python3網(wǎng)絡爬蟲實戰(zhàn)---28、解析庫的使用:XPath 本節(jié)我們利用 Reque...

    SwordFly 評論0 收藏0
  • Python3網(wǎng)絡爬蟲實戰(zhàn)---29、解析庫的使用:BeautifulSoup

    摘要:解析器在解析的時候實際上是依賴于解析器的,它除了支持標準庫中的解析器,還支持一些第三方的解析器比如,下面我們對支持的解析器及它們的一些優(yōu)缺點做一個簡單的對比。 上一篇文章:Python3網(wǎng)絡爬蟲實戰(zhàn)---28、解析庫的使用:XPath下一篇文章:Python3網(wǎng)絡爬蟲實戰(zhàn)---30、解析庫的使用:PyQuery 前面我們介紹了正則表達式的相關用法,但是一旦正則寫的有問題,可能得到的就...

    MockingBird 評論0 收藏0
  • python爬蟲爬取pixiv圖片實戰(zhàn)詳解

      小編寫這篇文章的主要目的,是來給大家做出一個介紹,介紹關于python爬蟲的一些技能技巧,包括怎么才能夠爬取pixiv圖片,作為一個小白來講,還是需要一定的實戰(zhàn)的,那么,具體的實戰(zhàn)技能,下面就給大家詳細的解答下。  自從接觸python以后就想著爬pixiv,之前因為梯子有點問題就一直擱置,最近換了個梯子就迫不及待試了下。  爬蟲無非request獲取html頁面然后用正則表達式或者beaut...

    89542767 評論0 收藏0

發(fā)表評論

0條評論

ityouknow

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<