正則表達(dá)式最佳實(shí)踐

Regular-Expressions

親胎撇,我的簡(jiǎn)書(shū)已不再維護(hù)和更新了箕母,所有文章都遷移到了我的個(gè)人博客:https://mikefighting.github.io/换吧,歡迎交流。

作為一名開(kāi)發(fā)人員,無(wú)論是前端柳沙,后端窟赏,移動(dòng)端妓柜,都可能會(huì)接觸到正則表達(dá)式,最常見(jiàn)的場(chǎng)景就是注冊(cè)登錄了涯穷,我們需要對(duì)電話號(hào)碼或者郵箱做校驗(yàn)棍掐,如果對(duì)用戶名有特殊字符有限制的話還會(huì)對(duì)特殊字符做校驗(yàn)。我們通常的做法就是百度或者谷歌拷况,最后復(fù)制粘貼完事作煌,對(duì)于那一串奇奇怪怪的字符串感覺(jué)很頭大。接下來(lái)的這篇文章會(huì)向你詳細(xì)解釋正則表達(dá)式的語(yǔ)法赚瘦,分析正則表達(dá)式粟誓,并且附帶上常用的表格,最后給出IOS中用到正則表達(dá)式的兩個(gè)類(lèi)NSRegularExpress起意,NSPredicate鹰服,NSString。

主要內(nèi)容包括

一揽咕、簡(jiǎn)介
二悲酷、正則表達(dá)式的PlayGround
三、基本語(yǔ)法表及簡(jiǎn)介
四亲善、正則表達(dá)式實(shí)例
五设易、正則表達(dá)式在IOS中
六、常用的正則表達(dá)式

一蛹头、簡(jiǎn)介

正則表達(dá)式就是一個(gè)用來(lái)檢索或者替換合乎某種條件的一串字符集顿肺。

二、正則表達(dá)式的PlayGround

在學(xué)習(xí)正則表達(dá)式時(shí)渣蜗,面對(duì)很多的長(zhǎng)篇大論屠尊,可能比較枯燥無(wú)味,寫(xiě)代碼跑項(xiàng)目又比較費(fèi)時(shí)費(fèi)力耕拷。regexpal網(wǎng)站需要翻墻)剛好可以解決我們的問(wèn)題知染,它可以隨時(shí)測(cè)試我們寫(xiě)的正則是否有誤,并且有語(yǔ)法檢查和語(yǔ)法提示斑胜。在接下來(lái)的說(shuō)明中控淡,可以邊看邊操作了嫌吠。

正則表達(dá)式的PlayGround

三、基本語(yǔ)法表及簡(jiǎn)介

正則表達(dá)式常用指令集
  • 純文本形式掺炭,比如a就將匹配文本中的a,如果Mike就會(huì)匹配文本中的Mike辫诅,文本之間是的關(guān)系。
  • ** 其中\是轉(zhuǎn)意字符涧狮,表示該字符后面的字母有特殊含義炕矮,比如下面要說(shuō)的\d,\b等,因?yàn)樵诤芏嗾Z(yǔ)言中者冤,比如0C肤视,Swift中\已經(jīng)是轉(zhuǎn)意字符,所以需要\\b來(lái)表示\b的含義涉枫。
  • []匹配里面的任何一個(gè)字符邢滑,比如p[abcde],將匹配pa愿汰,pb困后,pc,pd衬廷,pe摇予。當(dāng)然可以換成p[a-e],其中-表示“至”的意思,[0-9]表示0到9間的任何一個(gè)數(shù)字吗跋。
  • {}如上表侧戴,表示的是匹配的次數(shù),如{6}跌宛,表示匹配六次救鲤,{5,}表示匹配5次以上。比較難以理解的是{2,4}?秩冈,這表示最少匹配兩次,最多匹配四次斥扛,但是入问,如果四個(gè)字母同時(shí)出現(xiàn)了,就算兩個(gè)匹配稀颁,如果三個(gè)字母出現(xiàn)了芬失,就匹配兩次。如:正則[A-Z]{2,3}?匾灶,檢測(cè)MIKEF,就會(huì)產(chǎn)生兩個(gè)匹配MIKE棱烂,可以在上文的網(wǎng)站中練習(xí)。
  • .匹配任何一個(gè)字符阶女,比如M.M颊糜,匹配MuM哩治,MdM,M@M衬鱼,等业筏。
  • \w匹配很像單詞的字符,包含字母鸟赫,數(shù)字蒜胖,下劃線,但是不包含標(biāo)點(diǎn)符號(hào)抛蚤,及其他字符台谢,比如:hello\w,匹配hello_岁经,hello8朋沮,但是不匹配hello!
  • \d匹配數(shù)字蒿偎,其和[0-9]是同意的朽们。例如\d\d?:\d\d就是可以匹配時(shí)間,比如12:309:20等诉位。digital單詞的首字母
  • \b表示文字的邊界骑脱,比如空格和標(biāo)點(diǎn)符號(hào)。如go\b將會(huì)匹配go home和go!但是不會(huì)匹配gone苍糠,在需要匹配整個(gè)單詞的時(shí)候往往有用叁丧。boundary單詞的首字母
  • \s表示空格以及新的一行。比如Hey\s將會(huì)匹配Hey man!中的Hey岳瞭。
  • ^表示一行的開(kāi)頭拥娄,比如^Hello將會(huì)匹配Hello Everyone!但是不會(huì)匹配He said Hello。注意:在[]里面的^表示的非的意思瞳筏,如:[^DE]表示的是:不是DE的任何字符稚瘾。
  • ****表示行的結(jié)尾,例如end將會(huì)匹配it was the end但是不會(huì)匹配the end is comming姚炕。
  • *表示匹配其前面的字符0次或者很多次摊欠,如:go\*d,將會(huì)匹配good,goood,gooood,goooooood,gd等。
  • +表示匹配其前面的字符一次或者很多次柱宦,如:go+d將不會(huì)匹配gd些椒。
    注:關(guān)于強(qiáng)匹配的概念,如果想了解的可以掸刊!在正則ExpressionsInfo網(wǎng)站上學(xué)習(xí),捕獲的意思就是被捕獲的信息可以利用$n的形式來(lái)獲取并且用來(lái)做替換免糕。由于其使用不是很多,就不在贅述。

四石窑、正則表達(dá)式實(shí)例

經(jīng)過(guò)上面對(duì)正則表達(dá)式基本語(yǔ)法的講解及練習(xí)牌芋,我們來(lái)使用試著寫(xiě)幾個(gè)正則表達(dá)式。

1. 英文名字校驗(yàn)尼斧,規(guī)則如下:

  • 名字: 標(biāo)準(zhǔn)的英文字母姜贡,1到10個(gè)字母組成,首字母大寫(xiě)

  • Middle Name簡(jiǎn)寫(xiě):標(biāo)準(zhǔn)英文字母棺棵,1個(gè)字母楼咳,大小寫(xiě)都可以

  • 姓:標(biāo)準(zhǔn)的英文字母,可能有'(只能出現(xiàn)一個(gè))烛恤,比如: O’Brien母怜,長(zhǎng)度在2到10個(gè)字母,首字母大寫(xiě)
    根據(jù)上面的表格我們很容易寫(xiě)出這樣的

       名字:`^[A-Z][a-z]{1,9}$`,其中^表示一行的開(kāi)始[A-Z]表示第一個(gè)字母大寫(xiě)[a-z]表示中間的是小寫(xiě)字母缚柏,最后{1,9}表示1到9個(gè)字母苹熏,最后結(jié)尾是$
       MiddleName: `^[a-x]|[A-Z]$`,其中|表示或的意思
       姓:`^[A-Z]'?[a-z]{1,9}$`,其中'?表示'可以出現(xiàn)一次也可以不出現(xiàn)
    

2. 日期币喧,規(guī)則如下:

日期應(yīng)該在1/1/1900到31/12/2099年之間轨域,并且日期的格式必須是dd/mm/yyyydd-mm-yyyy或者dd.mm.yyyy這三種格式:參考上面的速查表,我們可以寫(xiě)出如下的正則表達(dá)式來(lái)

    ^0[1-9]|([1-2]\d)|3[01][/-.]0[1-9]|[1][012][/-.](19|20)\d\d$

其中日期:0[1-9]|([1-2]\\d)|3[01],也就是窮舉了所有的可能01,02,03...9,然后1或者2拼上\d杀餐,最后是3可能是30和31
月份:0[1-9]|[1][012],和前面的日期類(lèi)似干发,并且更少了,大于10的之后10,11,12幾種情況
年份:(19|20)\d\d前面是可能出現(xiàn)的年分19和20史翘,后面就是任意0-9的組合
分隔符:[/-.]只可能出現(xiàn)這三種情況枉长,所以用[]括起來(lái)即可

3. 日期加強(qiáng)版,規(guī)則如下:

格式是xx/xx/xx或xx.xx.xx或xx-xx-xx琼讽,分別是月必峰,日,年钻蹬,如:10-05-12表示12年10月5日吼蚁,其中月分可以是英文全拼也可能是縮寫(xiě),比如January->Jan问欠,F(xiàn)ebruary->Feb肝匆,日期可能第幾天,比如1st溅潜,2nd之類(lèi)的,月日年之間可以有不定的幾個(gè)空格薪伏,如March 13th, 2001:

     (\d{1,2}[-/.]\d{1,2}[-/.]\d{1,2})|(Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?)\s*\d{1,2}(st|nd|rd|th)?+[,]\s*\d{4}

我們可以先用()將其切開(kāi)滚澜,在用|將其切開(kāi)
先看全是數(shù)字的:(\d{1,2}[-/.]\d{1,2}[-/.]\d{1,2})表示兩個(gè)數(shù)字,兩個(gè)數(shù)字的組合嫁怀,如:10-05-12
然后看字母類(lèi)型的(Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?窮舉了所有的月份信息设捐,然后\s*表示任意多個(gè)空格借浊,然后是日期\d{1,2}(st|nd|rd|th)?再加若干個(gè)空格:\s*最后是四位數(shù)字。

4. 時(shí)間萝招,規(guī)則如下:

時(shí)間可以一位或者兩位蚂斤,數(shù)字,然后可以有若干個(gè)空格槐沼,最后是am或者pm曙蒸,經(jīng)過(guò)以上幾個(gè)例子,我們不難寫(xiě)出:\d{1,2}\s*[ab]m這樣的正則表達(dá)式

五岗钩、正則表達(dá)式在IOS中

一纽窟、NSRegularExpress

在IOS開(kāi)發(fā)中,我們經(jīng)常使用這個(gè)類(lèi)來(lái)做有關(guān)文本校驗(yàn)篩選工作兼吓,對(duì)于對(duì)象的校驗(yàn)經(jīng)常使用NSPredicate臂港,其使用非常簡(jiǎn)單,主要包含創(chuàng)建视搏,查找审孽,替換幾個(gè)方法:

    NSError *error = NULL;
    NSString *pattern = @"正則表達(dá)式";
    NSString *string = @"需要校驗(yàn)的文本";
    NSRange range = NSMakeRange(0, string.length);
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error]; // 創(chuàng)建RegularExpression對(duì)象
    NSArray *matches = [regex matchesInString:string options:NSMatchingProgress range:range]; // 找到校驗(yàn)的結(jié)果matches中是NSTextCheckingResult對(duì)象,該對(duì)象中包含各種被查找對(duì)象的信息
    
    // 下面兩個(gè)方法還可以幫們替換掉找到的字符
    - (NSString *)stringByReplacingMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range withTemplate:(NSString *)templ;
   - (NSUInteger)replaceMatchesInString:(NSMutableString *)string options:(NSMatchingOptions)options range:(NSRange)range withTemplate:(NSString *)templ;

二浑娜、NSPredicate和正則表達(dá)式結(jié)合

NSString    *regularExpression = @"正則表達(dá)式";
NSPredicate *numberPre = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regularExpression];
return [numberPre evaluateWithObject:textString];

三佑力、NSString的方法

-(NSRange)rangeOfString:(NSString *)aString options:(NSStringCompareOptions)mask;
NSRange range = [searchedText rangeOfString:@"正則表達(dá)式" options:NSRegularExpressionSearch];

六、常用的正則表達(dá)式

   1.驗(yàn)證用戶名和密碼:”^[a-zA-Z]\w{5,15}$”
  2.驗(yàn)證電話號(hào)碼:(”^(\\d{3,4}-)\\d{7,8}$”)
  eg:021-68686868  0511-6868686棚愤;
  3.驗(yàn)證手機(jī)號(hào)碼:”^1[3|4|5|7|8][0-9]\\d{8}$”搓萧;
  4.驗(yàn)證身份證號(hào)(15位或18位數(shù)字):”\\d{14}[[0-9],0-9xX]”;
  5.驗(yàn)證Email地址:(“^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\.\\w+([-.]\\w+)*$”)宛畦;
  6.只能輸入由數(shù)字和26個(gè)英文字母組成的字符串:(“^[A-Za-z0-9]+$”) ;
  7.整數(shù)或者小數(shù):^[0-9]+([.]{0,1}[0-9]+){0,1}$
  8.只能輸入數(shù)字:”^[0-9]*$”瘸洛。
  9.只能輸入n位的數(shù)字:”^\\d{n}$”。
  10.只能輸入至少n位的數(shù)字:”^\\d{n,}$”次和。
  11.只能輸入m~n位的數(shù)字:”^\\d{m,n}$”反肋。
  12.只能輸入零和非零開(kāi)頭的數(shù)字:”^(0|[1-9][0-9]*)$”。
  13.只能輸入有兩位小數(shù)的正實(shí)數(shù):”^[0-9]+(.[0-9]{2})?$”踏施。
  14.只能輸入有1~3位小數(shù)的正實(shí)數(shù):”^[0-9]+(\.[0-9]{1,3})?$”石蔗。
  15.只能輸入非零的正整數(shù):”^\+?[1-9][0-9]*$”。
  16.只能輸入非零的負(fù)整數(shù):”^\-[1-9][]0-9″*$畅形。
  17.只能輸入長(zhǎng)度為3的字符:”^.{3}$”养距。
  18.只能輸入由26個(gè)英文字母組成的字符串:”^[A-Za-z]+$”。
  19.只能輸入由26個(gè)大寫(xiě)英文字母組成的字符串:”^[A-Z]+$”日熬。
  20.只能輸入由26個(gè)小寫(xiě)英文字母組成的字符串:”^[a-z]+$”棍厌。
  21.驗(yàn)證是否含有^%&’,;=?$\”等字符:”[^%&',;=?$\x22]+”。
  22.只能輸入漢字:”^[\u4e00-\u9fa5]{0,}$”。
  23.驗(yàn)證URL:”^http://([\\w-]+\.)+[\\w-]+(/[\\w-./?%&=]*)?$”耘纱。
  24.驗(yàn)證一年的12個(gè)月:”^(0?[1-9]|1[0-2])$”正確格式為:”01″~”09″和”10″~”12″敬肚。
  25.驗(yàn)證一個(gè)月的31天:”^((0?[1-9])|((1|2)[0-9])|30|31)$”正確格式為;”01″~”09″束析、”10″~”29″和“30”~“31”艳馒。
  26.獲取日期正則表達(dá)式:\\d{4}[年|\-|\.]\\d{\1-\12}[月|\-|\.]\\d{\1-\31}日?
  評(píng)注:可用來(lái)匹配大多數(shù)年月日信息。
  27.匹配雙字節(jié)字符(包括漢字在內(nèi)):[^\x00-\xff]
  評(píng)注:可以用來(lái)計(jì)算字符串的長(zhǎng)度(一個(gè)雙字節(jié)字符長(zhǎng)度計(jì)2员寇,ASCII字符計(jì)1)
  28.匹配空白行的正則表達(dá)式:\n\s*\r
  評(píng)注:可以用來(lái)刪除空白行
  29.匹配HTML標(biāo)記的正則表達(dá)式:<(\S*?)[^>]*>.*?</>|<.*? />
  評(píng)注:網(wǎng)上流傳的版本太糟糕弄慰,上面這個(gè)也僅僅能匹配部分,對(duì)于復(fù)雜的嵌套標(biāo)記依舊無(wú)能為力
  30.匹配首尾空白字符的正則表達(dá)式:^\s*|\s*$
  評(píng)注:可以用來(lái)刪除行首行尾的空白字符(包括空格丁恭、制表符曹动、換頁(yè)符等等),非常有用的表達(dá)式
  31.匹配網(wǎng)址URL的正則表達(dá)式:[a-zA-z]+://[^\s]*
  評(píng)注:網(wǎng)上流傳的版本功能很有限牲览,上面這個(gè)基本可以滿足需求
  32.匹配帳號(hào)是否合法(字母開(kāi)頭墓陈,允許5-16字節(jié),允許字母數(shù)字下劃線):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
  評(píng)注:表單驗(yàn)證時(shí)很實(shí)用
  33.匹配騰訊QQ號(hào):[1-9][0-9]\{4,\}
  評(píng)注:騰訊QQ號(hào)從10 000 開(kāi)始
  34.匹配中國(guó)郵政編碼:[1-9]\\d{5}(?!\d)
  評(píng)注:中國(guó)郵政編碼為6位數(shù)字
  35.匹配ip地址:((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)第献。

七贡必、延伸閱讀:

  1. https://www.raywenderlich.com/30288/nsregularexpression-tutorial-and-cheat-sheet
  2. http://www.regexpal.com/
  3. http://nshipster.com/nspredicate/
  4. http://nshipster.com/nssortdescriptor/
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市庸毫,隨后出現(xiàn)的幾起案子仔拟,更是在濱河造成了極大的恐慌,老刑警劉巖飒赃,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件利花,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡载佳,警方通過(guò)查閱死者的電腦和手機(jī)炒事,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蔫慧,“玉大人挠乳,你說(shuō)我怎么就攤上這事」枚悖” “怎么了睡扬?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)黍析。 經(jīng)常有香客問(wèn)我卖怜,道長(zhǎng),這世上最難降的妖魔是什么阐枣? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任马靠,我火速辦了婚禮牍戚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘虑粥。我一直安慰自己,他們只是感情好宪哩,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布娩贷。 她就那樣靜靜地躺著,像睡著了一般锁孟。 火紅的嫁衣襯著肌膚如雪彬祖。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,784評(píng)論 1 290
  • 那天品抽,我揣著相機(jī)與錄音储笑,去河邊找鬼。 笑死圆恤,一個(gè)胖子當(dāng)著我的面吹牛突倍,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播盆昙,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼羽历,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了淡喜?” 一聲冷哼從身側(cè)響起秕磷,我...
    開(kāi)封第一講書(shū)人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎炼团,沒(méi)想到半個(gè)月后澎嚣,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瘟芝,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年易桃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片模狭。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡颈抚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出嚼鹉,到底是詐尸還是另有隱情贩汉,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布锚赤,位于F島的核電站匹舞,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏线脚。R本人自食惡果不足惜赐稽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一叫榕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧姊舵,春花似錦晰绎、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至史飞,卻和暖如春尖昏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背构资。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工抽诉, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吐绵。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓迹淌,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親己单。 傳聞我的和親對(duì)象是個(gè)殘疾皇子巍沙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

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