正則表達(dá)不再靠control+v(實(shí)操篇)

1. 前言

  • 前面的正則的基礎(chǔ)語(yǔ)法了解之后,正式開(kāi)始實(shí)際應(yīng)用
  • 對(duì)基礎(chǔ)知識(shí)感興趣的可以看看我寫(xiě)的基礎(chǔ)篇 《正則表達(dá)不再control+v》
  • 結(jié)尾有一些常用的正則表達(dá)式,但是想了解為什么還是最好順序閱讀
    awesome.JPG

2.子表達(dá)式

2.1 概念

  • ()括起來(lái)的就是子表達(dá)式
  • 我的理解:子表達(dá)式的目的是為了增加匹配的優(yōu)先級(jí),子表達(dá)式內(nèi)的優(yōu)先級(jí)較高,優(yōu)先匹配
  • 子表達(dá)式可以嵌套,這個(gè)在下面會(huì)通過(guò)例子來(lái)解釋

2.2 實(shí)戰(zhàn)-IP地址的匹配

  • 我們會(huì)一步一步完善和簡(jiǎn)化一個(gè)IP的正則表達(dá)式

  • 需求分析:IP 地址是由.分隔的四組數(shù)字,如192.168.1.106。因?yàn)槊總€(gè)部分的數(shù)字都可以為1-3位數(shù)字字符

    IP地址匹配1.0.png

  • 分析

    first:\d{1,3}表示匹配一個(gè)由數(shù)字組成的1-3位的字符串
    second:\d{1,3}\.表示1-3位數(shù)字,并以.結(jié)尾
    third:最后一組字符串不需要以.結(jié)尾,所以\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}貌似可以解決IP的匹配

  • 但是d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}這個(gè)正則,重復(fù)表達(dá)式太多,垃圾代碼那么多能忍么???那么子表達(dá)式就出現(xiàn)用處了

    IP地址匹配1.0-子表達(dá)式簡(jiǎn)化版.png

  • 分析

    \d{1,3}\.()子表達(dá)式括起來(lái),并加上重復(fù)執(zhí)行次數(shù),能簡(jiǎn)化正則的可閱讀性

  • 那么我們的IP正則的容錯(cuò)性到底怎么樣?


    IP地址匹配-非法IP校驗(yàn).png
  • 非法IP也能被匹配,說(shuō)明我們的IP匹配有問(wèn)題,其實(shí)是需求分析有問(wèn)題,IP的地址規(guī)則并未完全體現(xiàn),那么補(bǔ)充需求之后再完善我們的IP地址匹配吧

IP地址規(guī)則:

  1. 所有的一位數(shù)和兩位數(shù)
  2. 三位數(shù)的第一位為 1
  3. 如果三位數(shù)的第一位為 2 ,且第二位從 0 到 4
  4. 如果三位數(shù)的前二位為 25 ,且第三位從 0 到 5
  5. 總結(jié):0-255.0-255.0-255.0-255 就是我們要寫(xiě)的
  • 明確了規(guī)則,把每條規(guī)則實(shí)現(xiàn)即可


    IP地址匹配2.0.png
  • 新的實(shí)現(xiàn)(((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5])),一個(gè)匹配里嵌套了四組子表達(dá)式

解析:
1.將整個(gè)正則拆成兩個(gè)部分((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5])),前一部分重復(fù)三次用來(lái)表示前面三組數(shù)字,并且以.結(jié)尾,后一部分表示最后一組IP地址
2.第一部分:(\d{1,2}),這個(gè)子表達(dá)式將匹配一位或者兩位任意數(shù)字
3.第二部分:((1\d{2}),這個(gè)子表達(dá)式將匹配以1開(kāi)頭的后兩位任意數(shù)字的三位數(shù)字
4.第三部分:(2[0-4]\d),這個(gè)子表達(dá)式將匹配以2開(kāi)頭的中間一位為0-4,第三位為任意數(shù)字的字符串
5.第四部分:(25[0-5]),這個(gè)子表達(dá)式將匹配以25開(kāi)頭的尾數(shù)為0-5的三位數(shù)字

  • 還有網(wǎng)上很多別的寫(xiě)法,但是我覺(jué)得這個(gè)寫(xiě)法是比較好理解的版本,所以如果有更好的,可以告訴我,畢竟我覺(jué)得真的很長(zhǎng)

2.3 年份匹配

  • 這個(gè)需求很簡(jiǎn)單,就是匹配19xx-20xx所有年份
  • 目的:體驗(yàn)子表達(dá)式的優(yōu)先級(jí)
  • 實(shí)用性:我覺(jué)得這種簡(jiǎn)單的正則在開(kāi)發(fā)中實(shí)用性很強(qiáng),很多都可以用到
    年份匹配-錯(cuò)誤版本.png
  • 解釋

1.19|20\d{2}這個(gè)表達(dá)式?jīng)]有達(dá)到我們的效果
2.這個(gè)表達(dá)式其實(shí)的效果是匹配19(兩位)和以20開(kāi)頭的四位數(shù)字
3.這里就能體現(xiàn)子表達(dá)式的效果,我們想要的是19或者20開(kāi)頭的四位數(shù)字,那么我們完全可以這部分用子表達(dá)式括起來(lái),來(lái)實(shí)現(xiàn)效果

年份匹配-正確版本.png

2.4 HTML標(biāo)簽匹配

  • 需求:匹配H5標(biāo)簽,因?yàn)镠5標(biāo)簽的格式還是很固定的<xxx>xxx</xxx>
  • 知識(shí)點(diǎn):這里會(huì)用到向后引用這個(gè)寫(xiě)法
  • 以匹配H標(biāo)簽為例


    標(biāo)簽匹配-錯(cuò)誤版.png
  • 這里就有個(gè)需求就是前面和后面的相同匹配規(guī)則匹配保持一致,比如前面匹配了H2標(biāo)簽,后面還是要匹配H2標(biāo)簽,前后一致

2.4.1 后向引用

  • 后向引用就是引用前面的子表達(dá)式
  • 使用小括號(hào)指定一個(gè)子表達(dá)式后,匹配這個(gè)子表達(dá)式的文本(也就是此分組捕獲的內(nèi)容)可以在表達(dá)式或其他程序中作進(jìn)一步處理。默認(rèn)情況下,每個(gè)分組會(huì)自動(dòng)擁有一個(gè)組號(hào),規(guī)則是:從左向右,以分組的左括號(hào)為標(biāo)志,第一個(gè)出現(xiàn)的分組的組號(hào)為1,第二個(gè)為2,以此類(lèi)推
  • 后向引用用于重復(fù)搜索前面某個(gè)分組匹配的文本
  • 可以參考文章: 正則表達(dá)式后向引用~~~~~~ & 正則表達(dá)式后向引用

2.4.2 HTML標(biāo)簽匹配之向后引用

  • 但是我這里遇到了個(gè)問(wèn)題:使用Regextor出現(xiàn)了不能匹配正確的向后引用,我不確定是APP不能識(shí)別這種語(yǔ)法還是什么原因,如果有知道請(qǐng)告訴我
    Regextor不支持向后引用么?.png
  • 我們?cè)趚code中使用了匹配查詢(xún),這個(gè)正則完全能達(dá)到我們的要求


    xcode匹配結(jié)果.png
  • <[hH]([1-5])>.*?</[hH]\1>分析

<[hH]([1-5])>中將第一個(gè)子表達(dá)式使用()括起來(lái),在緩存中使用這個(gè)子表達(dá)式默認(rèn)為第一個(gè)分組
</[hH]\1>\1使用第一個(gè)的子表達(dá)式的匹配取值應(yīng)用到第二處,不如前面匹配了1,后面只能匹配1

3,實(shí)際開(kāi)發(fā)應(yīng)用

3.1 查找替換文本

  • 2.4.2 HTML標(biāo)簽的匹配中就用xcode的查找操作


    xcode匹配.png

3.2 校驗(yàn)字符串是否符合規(guī)則-NSPredicate

  • 最常用的一種方式
NSString *string = @"hotCat";
//正則
NSString *regex = @"^ho[a-zA-Z]{2,}*$";
//創(chuàng)建NSPredicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
BOOL result = [predicate evaluateWithObject:string];

3.3 字符串某一個(gè)字符或者字符集的定位

  • 用處:特定的字符串的替換,或者某些字符的刪除,都可以使用,因?yàn)榭梢阅玫?strong>想要的NSRange
NSString *string = @"hotCat123";
//使用正則\d+去string中進(jìn)行匹配,得到的時(shí)匹配到的range,在這里為{4,3}。
NSRange range = [string rangeOfString:@"\\d+" options:NSRegularExpressionSearch];
//如果匹配到就打印匹配到的子字符串,在這里為123。
if (range.location != NSNotFound)
{
    NSLog(@"%@",[string substringWithRange:range]);
}

分析:
1.\d+用來(lái)查找數(shù)字
2.rangeOfString:options:會(huì)返回一個(gè)NSRange,用來(lái)接收匹配的范圍options必須要用NSRegularExpressionSearch,代表用正則去匹配
3.當(dāng)寫(xiě)正則字符串時(shí),\需要寫(xiě)成\\ ,所以,\d+需要寫(xiě)成\\d+

3.4 NSRegularExpression

  • NSRegularExpression這個(gè)類(lèi)可以用戶(hù)來(lái)查找字符串中符合要求的第一個(gè)匹配結(jié)果或者所有匹配結(jié)果
  • 這個(gè)使用很簡(jiǎn)單,就不詳細(xì)介紹了,如果有想知道使用的,可以移步oc中正則表達(dá)式NSRegularExpression類(lèi)詳解

3.5 其它

  • 我覺(jué)得還可以有很多高級(jí)的用處,但是實(shí)際開(kāi)發(fā)中還沒(méi)遇到,如果有遇到可以告訴我,我會(huì)去在深入學(xué)習(xí)下,謝謝啦!!!

4. 最后的福利

  • 最后的留一些常用的校驗(yàn)吧,以免有人偷懶,所以寫(xiě)在最后,但是可能不知道是否符合最新的標(biāo)準(zhǔn),比如手機(jī)號(hào)碼,新字段開(kāi)發(fā)太快了
/**
     * 手機(jī)號(hào)碼:
     * 13[0-9], 14[5,7], 15[0, 1, 2, 3, 5, 6, 7, 8, 9], 17[0, 1, 6, 7, 8], 18[0-9]
     * 移動(dòng)號(hào)段: 134,135,136,137,138,139,147,150,151,152,157,158,159,170,178,182,183,184,187,188
     * 聯(lián)通號(hào)段: 130,131,132,145,155,156,170,171,175,176,185,186
     * 電信號(hào)段: 133,149,153,170,173,177,180,181,189
     */
    NSString *MOBILE = @"^1(3[0-9]|4[57]|5[0-35-9]|7[0135678]|8[0-9])\\d{8}$";
    /**
     * 中國(guó)移動(dòng):China Mobile
     * 134,135,136,137,138,139,147,150,151,152,157,158,159,170,178,182,183,184,187,188
     */
    NSString *CM = @"^1(3[4-9]|4[7]|5[0-27-9]|7[08]|8[2-478])\\d{8}$";
    /**
     * 中國(guó)聯(lián)通:China Unicom
     * 130,131,132,145,155,156,170,171,175,176,185,186
     */
    NSString *CU = @"^1(3[0-2]|4[5]|5[56]|7[0156]|8[56])\\d{8}$";
    /**
     * 中國(guó)電信:China Telecom
     * 133,149,153,170,173,177,180,181,189
     */
    NSString *CT = @"^1(3[3]|4[9]|53|7[037]|8[019])\\d{8}$";


郵箱:   ^[a-zA-Z0-9]{4,}@[a-z0-9A-Z]{2,}\\.[a-zA-Z]{2,}$
大陸固定電話(huà)號(hào)碼:    ^\\d{4}-|\\d{3}-)?(\\d{8}|\\d{7}$
身份證號(hào):    \\d{14}[[0-9],0-9xX]
Email地址:    ^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\.\\w+([-.]\\w+)*$
純數(shù)字:   ^[0-9]*$
由數(shù)字和英文字母組成:   ^[A-Za-z0-9]+$
QQ號(hào):   ^[1-9][0-9]\{4,\}$
中國(guó)郵政編碼:   ^[1-9]\\d{5}(?!\\d)$
URL:  ^http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?$
純漢字中文:^[\u4e00-\u9fa5]{0,}$

Thanks.JPG
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,739評(píng)論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,634評(píng)論 3 419
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,653評(píng)論 0 377
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,063評(píng)論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,835評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,235評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,315評(píng)論 3 442
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,459評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,000評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,819評(píng)論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,004評(píng)論 1 370
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,560評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,257評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,676評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,937評(píng)論 1 288
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,717評(píng)論 3 393
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,003評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容