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

1. 前言

  • 前面的正則的基礎(chǔ)語(yǔ)法了解之后,正式開(kāi)始實(shí)際應(yīng)用
  • 對(duì)基礎(chǔ)知識(shí)感興趣的可以看看我寫的基礎(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 就是我們要寫的
  • 明確了規(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)上很多別的寫法,但是我覺(jué)得這個(gè)寫法是比較好理解的版本,所以如果有更好的,可以告訴我,畢竟我覺(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è)寫法
  • 以匹配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,以此類推
  • 后向引用用于重復(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中使用了匹配查詢,這個(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)寫正則字符串時(shí),\需要寫成\\ ,所以,\d+需要寫成\\d+

3.4 NSRegularExpression

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

3.5 其它

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

4. 最后的福利

  • 最后的留一些常用的校驗(yàn)吧,以免有人偷懶,所以寫在最后,但是可能不知道是否符合最新的標(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,}$
大陸固定電話號(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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容