成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

這次不會(huì)說(shuō)我的正則教程沒(méi)寫(xiě)全了吧??

zhunjiee / 2832人閱讀

摘要:負(fù)向先行斷言負(fù)前瞻語(yǔ)法作用匹配非表達(dá)式的前面內(nèi)容,不返回本身。我們來(lái)測(cè)試一下輸出結(jié)果嗯,這就是我們想要的了。

由于上一篇文章:《正則表達(dá)式真的很騷,可惜你不會(huì)寫(xiě)!??!》 發(fā)表之后,不少網(wǎng)友說(shuō)怎么沒(méi)講斷言沒(méi)講反向沒(méi)講貪婪....,甚至有老鐵說(shuō)我褲子都脫了你就給講了一點(diǎn),哈哈哈,好吧,趁著山竹臺(tái)風(fēng)被迫放假在家的時(shí)間,把正則剩余的一些知識(shí)點(diǎn)給講一下,希望大家喜歡,希望這次脫褲子閱讀的老鐵可以暢快的操作了。

本文旨在用最通俗的語(yǔ)言講述最枯燥的基本知識(shí)。

文章提綱:

零寬斷言

捕獲和非捕獲

反向引用

貪婪和非貪婪

反義

1. 零寬斷言

無(wú)論是零寬還是斷言,聽(tīng)起來(lái)都古古怪怪的,
那先解釋一下這兩個(gè)詞。

斷言:俗話(huà)的斷言就是“我斷定什么什么”,而正則中的斷言,就是說(shuō)正則可以指明在指定的內(nèi)容的前面或后面會(huì)出現(xiàn)滿(mǎn)足指定規(guī)則的內(nèi)容,意思正則也可以像人類(lèi)那樣斷定什么什么,比如"ss1aa2bb3",正則可以用斷言找出aa2前面有bb3,也可以找出aa2后面有ss1.

零寬:就是沒(méi)有寬度,在正則中,斷言只是匹配位置,不占字符,也就是說(shuō),匹配結(jié)果里是不會(huì)返回?cái)嘌员旧怼?/p>

意思是講明白了,那他有什么用呢?
我們來(lái)舉個(gè)栗子:
假設(shè)我們要用爬蟲(chóng)抓取csdn里的文章閱讀量。通過(guò)查看源代碼可以看到文章閱讀量這個(gè)內(nèi)容是這樣的結(jié)構(gòu)

"閱讀數(shù):641"

其中只有‘641’這個(gè)是一個(gè)變量,也就是不同文章有不同的值,當(dāng)我們拿到這個(gè)字符串時(shí),需要獲得這里邊的‘641’有很多種辦法,但如果使用正則應(yīng)該怎么匹配呢?

下面先講一下幾種類(lèi)型的斷言:

正向先行斷言(正前瞻):

語(yǔ)法:(?=pattern)

作用:匹配pattern表達(dá)式的前面內(nèi)容,不返回本身。

這樣子說(shuō),還是一臉懵逼,好吧,回歸剛才那個(gè)栗子,要取到閱讀量,在正則表達(dá)式中就意味著要能匹配到‘’前面的數(shù)字內(nèi)容
按照上所說(shuō)的正向先行斷言可以匹配表達(dá)式前面的內(nèi)容,那意思就是:(?=) 就可以匹配到前面的內(nèi)容了。
匹配什么內(nèi)容呢?如果要所有內(nèi)容那就是:

String reg=".+(?=)";

String test = "閱讀數(shù):641";
Pattern pattern = Pattern.compile(reg);
Matcher mc=    pattern.matcher(test);
while(mc.find()){
  System.out.println("匹配結(jié)果:")
  System.out.println(mc.group());
}

//匹配結(jié)果:
//閱讀數(shù):641

可是老哥我們要的只是前面的數(shù)字呀,那也簡(jiǎn)單咯,匹配數(shù)字 d,那可以改成:

String reg="d+(?=)";
String test = "閱讀數(shù):641";
Pattern pattern = Pattern.compile(reg);
Matcher mc=    pattern.matcher(test);
while(mc.find()){
  System.out.println(mc.group());
}
//匹配結(jié)果:
//641

大功告成!

正向后行斷言(正后顧):

語(yǔ)法:(?<=pattern)

作用:匹配pattern表達(dá)式的后面的內(nèi)容,不返回本身。

有先行就有后行,先行是匹配前面的內(nèi)容,那后行就是匹配后面的內(nèi)容啦。
上面的栗子,我們也可以用后行斷言來(lái)處理.

//(?<=閱讀數(shù):)d+
String reg="(?<=閱讀數(shù):)d+";

String test = "閱讀數(shù):641";
Pattern pattern = Pattern.compile(reg);
Matcher mc=    pattern.matcher(test);
        while(mc.find()){
            System.out.println(mc.group());
        }
//匹配結(jié)果:
//641

就這么簡(jiǎn)單。

負(fù)向先行斷言(負(fù)前瞻)

語(yǔ)法:(?!pattern)

作用:匹配非pattern表達(dá)式的前面內(nèi)容,不返回本身。

有正向也有負(fù)向,負(fù)向在這里其實(shí)就是非的意思。
舉個(gè)栗子:比如有一句 “我愛(ài)祖國(guó),我是祖國(guó)的花朵”
現(xiàn)在要找到不是"的花朵"前面的祖國(guó)
用正則就可以這樣寫(xiě):

祖國(guó)(?!的花朵)

負(fù)向后行斷言(負(fù)后顧)

語(yǔ)法:(?

作用:匹配非pattern表達(dá)式的后面內(nèi)容,不返回本身。

2. 捕獲和非捕獲

單純說(shuō)到捕獲,他的意思是匹配表達(dá)式,但捕獲通常和分組聯(lián)系在一起,也就是“捕獲組”

捕獲組:匹配子表達(dá)式的內(nèi)容,把匹配結(jié)果保存到內(nèi)存中中數(shù)字編號(hào)或顯示命名的組里,以深度優(yōu)先進(jìn)行編號(hào),之后可以通過(guò)序號(hào)或名稱(chēng)來(lái)使用這些匹配結(jié)果。

而根據(jù)命名方式的不同,又可以分為兩種組:

數(shù)字編號(hào)捕獲組:

語(yǔ)法:(exp)
解釋?zhuān)簭谋磉_(dá)式左側(cè)開(kāi)始,每出現(xiàn)一個(gè)左括號(hào)和它對(duì)應(yīng)的右括號(hào)之間的內(nèi)容為一個(gè)分組,在分組中,第0組為整個(gè)表達(dá)式,第一組開(kāi)始為分組。
比如固定電話(huà)的:020-85653333
他的正則表達(dá)式為:(0d{2})-(d{8})
按照左括號(hào)的順序,這個(gè)表達(dá)式有如下分組:

序號(hào) 編號(hào) 分組 內(nèi)容
0 0 (0d{2})-(d{8}) 020-85653333
1 1 (0d{2}) 020
2 2 (d{8}) 85653333

我們用Java來(lái)驗(yàn)證一下:

String test = "020-85653333";
        String reg="(0d{2})-(d{8})";
        Pattern pattern = Pattern.compile(reg);
        Matcher mc=    pattern.matcher(test);
        if(mc.find()){
            System.out.println("分組的個(gè)數(shù)有:"+mc.groupCount());
            for(int i=0;i<=mc.groupCount();i++){
                System.out.println("第"+i+"個(gè)分組為:"+mc.group(i));
            }
        }

輸出結(jié)果:

分組的個(gè)數(shù)有:2
第0個(gè)分組為:020-85653333
第1個(gè)分組為:020
第2個(gè)分組為:85653333

可見(jiàn),分組個(gè)數(shù)是2,但是因?yàn)榈?個(gè)為整個(gè)表達(dá)式本身,因此也一起輸出了。

命名編號(hào)捕獲組:

語(yǔ)法:(?exp)
解釋?zhuān)悍纸M的命名由表達(dá)式中的name指定
比如區(qū)號(hào)也可以這樣寫(xiě):(?0d{2})-(?d{8})
按照左括號(hào)的順序,這個(gè)表達(dá)式有如下分組:

序號(hào) 名稱(chēng) 分組 內(nèi)容
0 0 (0d{2})-(d{8}) 020-85653333
1 quhao (0d{2}) 020
2 haoma (d{8}) 85653333

用代碼來(lái)驗(yàn)證一下:

String test = "020-85653333";
        String reg="(?0d{2})-(?d{8})";
        Pattern pattern = Pattern.compile(reg);
        Matcher mc=    pattern.matcher(test);
        if(mc.find()){
            System.out.println("分組的個(gè)數(shù)有:"+mc.groupCount());
            System.out.println(mc.group("quhao"));
            System.out.println(mc.group("haoma"));
        }

輸出結(jié)果:

分組的個(gè)數(shù)有:2
分組名稱(chēng)為:quhao,匹配內(nèi)容為:020
分組名稱(chēng)為:haoma,匹配內(nèi)容為:85653333

非捕獲組:

語(yǔ)法:(?:exp)
解釋?zhuān)汉筒东@組剛好相反,它用來(lái)標(biāo)識(shí)那些不需要捕獲的分組,說(shuō)的通俗一點(diǎn),就是你可以根據(jù)需要去保存你的分組。

比如上面的正則表達(dá)式,程序不需要用到第一個(gè)分組,那就可以這樣寫(xiě):

(?: