iOS中使用正則表達式就不得不提NSRegularExpression碌尔,所以我們需要先搞清楚什么是NSRegularExpression腔剂,養(yǎng)成好習慣先查看下文檔:NSRegularExpression文檔吞琐,看到文檔中的第一段:
# 原文:
The NSRegularExpression class is used to represent and apply regular expressions to Unicode strings. An instance of this class is an immutable representation of a compiled regular expression pattern and various option flags. The pattern syntax currently supported is that specified by ICU. The ICU regular expressions are described athttp://userguide.icu-project.org/strings/regexp.
大概翻譯(翻譯可能不太準懂扼,但是意思大概就是這樣烁落。建議大家看原文熄云。):
NSRegularExpression是用Unicode字符串表達和應用正則表達式的類塌衰。這個類的實例是代表一個不可變的正則表達式和選項標識诉稍。當前支持的語法是ICU蝠嘉。ICU正則表達式的具體說明在:http://userguide.icu-project.org/strings/regexp
第一段話給了我們4個信息:
1) NSRegularExpression支持的是Unicode字符,代表可以輸入所有字符杯巨。
2) NSRegularExpression實例的表達式內容和選項標識是不能改變的是晨。直接查看NSRegularExpression的.h文件:
```
@interface NSRegularExpression:NSObject ()
@property(readonly,copy)NSString*pattern;
@property(readonly)NSRegularExpressionOptionsoptions;
+ (nullableNSRegularExpression*)regularExpressionWithPattern:(NSString*)pattern options:(NSRegularExpressionOptions)options error:(NSError**)error;
- (nullable instancetype)initWithPattern:(NSString*)pattern options:(NSRegularExpressionOptions)options error:(NSError**)errorNS_DESIGNATED_INITIALIZER;
@end
```
從.h文件中可以看出,屬性pattern和options是用readonly修飾的代表著只讀不可賦值舔箭,在初始化的時候可以賦值罩缴。
3) NSRegularExpression支持的ICU正則表達式語法。
4.)ICU正則表達式的詳解地址:http://userguide.icu-project.org/strings/regexp(這個被墻了层扶,需要翻墻箫章。)
ICU正則表達式是基于Perl正則表達式的,而Perl正則表達式則是基于Version 8 Regular Expressions镜会,有興趣的可以自行查閱:ICU Regular Expressions檬寂,Perl Regular Expressions,Version 8 Regular Expressions,在這里就不祥說了戳表。
Flag Options
先看到文檔中的Flag Options桶至,標識選項。如下表:
Flag Options描述
i不區(qū)分大小寫
x允許空格和注釋
s.匹配行終止符匾旭,默認情況下是不匹配的
m^和$匹配每一行的開頭和結尾镣屹,默認情況下是只匹配文本開頭和結尾。
Para如果設置了价涝,字的邊界按照Unicode UAX 29中的文本邊界發(fā)現單詞的定義女蜈。默認情況下,字邊界由字符的簡單分類為“word”或“non-word”色瘩,這近似于傳統(tǒng)正則表達式行為的手段鑒定伪窖。用兩個選擇獲得的結果可以是在空間和其他非單詞字符的運行完全不同。
我們再來看看NSRegularExpressionOptions:
typedefNS_OPTIONS(NSUInteger, NSRegularExpressionOptions){? NSRegularExpressionCaseInsensitive? ? ? ? ? ? =1<<0,/* Match letters in the pattern independent of case. */NSRegularExpressionAllowCommentsAndWhitespace? =1<<1,/* Ignore whitespace and #-prefixed comments in the pattern. */NSRegularExpressionIgnoreMetacharacters? ? ? ? =1<<2,/* Treat the entire pattern as a literal string. */NSRegularExpressionDotMatchesLineSeparators? ? =1<<3,/* Allow . to match any character, including line separators. */NSRegularExpressionAnchorsMatchLines? ? ? ? ? =1<<4,/* Allow ^ and $ to match the start and end of lines. */NSRegularExpressionUseUnixLineSeparators? ? ? =1<<5,/* Treat only \n as a line separator (otherwise, all standard line separators are used). */NSRegularExpressionUseUnicodeWordBoundaries? ? =1<<6/* Use Unicode TR#29 to specify word boundaries (otherwise, traditional regular expression word boundaries are used). */};
其實上面的注釋已經說的很清楚了居兆。
typedefNS_OPTIONS(NSUInteger, NSRegularExpressionOptions){? NSRegularExpressionCaseInsensitive? ? ? ? ? ? =1<<0,/* 匹配是不區(qū)分大小寫 */NSRegularExpressionAllowCommentsAndWhitespace? =1<<1,/* 忽略空白和注釋 */NSRegularExpressionIgnoreMetacharacters? ? ? ? =1<<2,/* 將所有的patter當作普通字符串覆山,例如:$\[]()+*^.|*/NSRegularExpressionDotMatchesLineSeparators? ? =1<<3,/* .匹配換行和空格 */NSRegularExpressionAnchorsMatchLines? ? ? ? ? =1<<4,/* $,^匹配每一行的開頭和結尾 */NSRegularExpressionUseUnixLineSeparators? ? ? =1<<5,/* 行分隔符只有\(zhòng)n(否則,所有標準的行分隔符時泥栖,例如\r也是換行) */NSRegularExpressionUseUnicodeWordBoundaries? ? =1<<6/* 使用 Unicode TR#29 規(guī)定的邊界簇宽。(否則,使用傳統(tǒng)的正則表達式的詞邊界) */};
Regular Expression Metacharacters(正則表達式元字符)
元字符表如下:
字符表達式描述
\a匹配Bell(響鈴)聊倔,\u0007晦毙,ASCII表第七位
\A匹配文本開頭,和^不同的是不能匹配換行的開頭耙蔑。^在NSRegularExpressionAnchorsMatchLines條件下可以匹配每一行的開頭,同樣$也是一樣
\b匹配詞的前面后面孤荣,或者后面甸陌,例如:匹配字符串為這是一個test代碼.须揣,正則為t\b或者\bt,前者匹配t結尾钱豁,后者匹配t開頭耻卡,你可以理解為\b表示邊界。分隔符可以是特殊字符或者中文牲尺。
\B文檔原話是這樣的:Match if the current position is not a word boundary.卵酪,意思應該是:如果當前位置不是邊界則匹配。很容易讓人理解為\B修飾的字符串不在邊界谤碳,然而實際情況并不是這樣溃卡。可以把\B理解為非邊界蜒简,例如待匹配字符串有:test瘸羡、tes、est搓茬,我們需要匹配的es在不在頭部也不再尾部的字符串犹赖,相對應的正則應該是:\Bes\B,如果正則是\Bes則會匹配到:test和tes卷仑,正則是es\B則會匹配到:test和est
\cX匹配控制字符峻村,例如\cM匹配control-M或者回車,點擊查看更多的控制字符
\d匹配10進制數锡凝,0~9
\D匹配非10進制數
\E配合\Q使用雀哨,\Q開頭\E結尾,中間的字符串都會被當作普通字符串私爷。例如:\Q$\E等價于\$
\e匹配空格, \u001B
\f匹配\u000F
\n匹配\u000A
\G連續(xù)匹配雾棺,從當前位置開始匹配一直匹配到第一個不匹配的地方結束,例如待匹配字符串test1test衬浑,正則[a-z]可以匹配8個字符捌浩,如果正則是\Gtest則能匹配4個,如果待匹配字符串為:1test1test工秩,正則:\Gtest將匹配不到任何字符串尸饺,正則:1\Gtest能匹配到4個字符
\N{UNICODE CHARACTER NAME}Match the named character.(具體作用和使用方式不明。助币。浪听。。)
\p{UNICODE PROPERTY NAME}匹配指定的UNICODE屬性名的字符眉菱,例如:屬性名:Lu代表的是大寫字母迹栓,待匹配字符串:Test,正則:\p{Lu}俭缓,匹配結果是T克伊。更多屬性名
\P{UNICODE PROPERTY NAME}匹配非指定UNICODE屬性名的字符酥郭,例如:屬性名:Lu代表的是大寫字母,待匹配字符串:Test愿吹,正則:\P{Lu}不从,匹配結果是e,s犁跪,t椿息。更多屬性名
\Q配合\E使用,\Q開頭\E結尾坷衍,中間的字符串都會被當作普通字符串寝优。例如:\Q$\E等價于\$
\r換號符,\u000D.
\t制表符惫叛, \u0009
\s空白字符串倡勇,[\t\n\f\r\p{Z}]
\S非空白字符串, [^\t\n\f\r\p{Z}]
\uhhhh16進制直為hhhh的字符串
\uhhhhhhhh16進制直為hhhhhhhh的字符串
\w非字符
\W字符
\x{hhhh}16進制值為hhhh的字符
\xhh16進制值為hh的字符
\X官方文檔解釋:Match a Grapheme Cluster.
\Z結束輸入嘉涌,文檔原文:Match if the current position is at the end of input, but before the final line terminator, if one exists.妻熊。
\z結束輸入,文檔原文:Match if the current position is at the end of input.
\n換行符仑最,\u000A
\0ooo8進制值為ooo的字符串
[pattern]pattern表示要匹配的字符串扔役,例如[A]表示匹配A
.任意字符
^開頭
$結尾
\轉義,例如匹配$警医,正則:\$
上表是筆者對文檔中的元字符理解亿胸,有幾個筆者也不清楚例如:\N{UNICODE CHARACTER NAME}怎么使用和具備什么作用。
正則表達式操作符
操作符表:
操作符描述
丨丨或预皇,例如A丨B侈玄,匹配A或B
*0次或者多次
+1次或者多次
?0次或1次
{n}n為數字,表示前面匹配連續(xù)出現n次吟温,例如:3{2}表示33
{n,}n為數字序仙,表示前面匹配至少連續(xù)出現n次,例如:3{2,}鲁豪,表示:33潘悼,333,3333...}
{n,m}n,m為數字爬橡,n<=m治唤,表示前面匹配連續(xù)出現n~m次,例如:3{2,5}糙申,表示:33宾添,333,3333,33333
*?0次或者多次辞槐,但是次數盡可能少掷漱,例如正則:[\d]*?,待匹配字符:12345,匹配次數6次粘室,都是空
+?1次或者多次榄檬,但是次數盡可能少,例如正則:[\d]+?,待匹配字符:12345衔统,匹配次數5次鹿榜,匹配結果是:1,2锦爵,3舱殿,4,5险掀。
??0次或1次沪袭,例如正則:[\d]??,待匹配字符:12345,匹配次數6次,都是空
{n}?同{n}
{n,}?n為數字樟氢,但是次數盡可能少冈绊。例如正則:[\d]{1,}?,待匹配字符:12345,匹配次數5次,匹配結果是:1埠啃,2死宣,3,4碴开,5毅该。
{n,m}?同{n,m},但是次數盡可能少潦牛。例如正則:[\d]{1,5}?,待匹配字符:12345,匹配次數5次眶掌,匹配結果是:1,2巴碗,3朴爬,4,5良价。
*+0次或者多次寝殴,但是次數盡可能多(貪婪模式)。例如正則:[\d]*+,待匹配字符:12345,匹配次數2次明垢,匹配結果是:12345和空蚣常。
++1次或者多次,但是次數盡可能多(貪婪模式)痊银。例如正則:[\d]*+,待匹配字符:12345,匹配次數1次抵蚊,匹配結果是:12345。
?+0次或1次,但是次數盡可能多(貪婪模式)贞绳。例如正則:[\d]*+,待匹配字符:12345,匹配次數5次谷醉,匹配結果是:1,2冈闭,3俱尼,4,5萎攒。
{n}+同{n}
{n,}+同{n,}遇八,但是次數盡可能多(貪婪模式)。例如正則:[\d]{1,}+,待匹配字符:12345,匹配次數1次耍休,匹配結果是:12345刃永。
{n,m}+同{n,m},但是次數盡可能多(貪婪模式)羊精。例如正則:[\d]{1,5}+,待匹配字符:12345,匹配次數1次斯够,匹配結果是:12345。
(...)子表達式喧锦,并捕獲匹配字符(捕獲和不捕獲的區(qū)別在后面會介紹)读规,例如:待匹配字符串:``
(?:...)匹配子表達式...,但是不捕獲字符(捕獲和不捕獲的區(qū)別在后面會介紹)
(?>...)貪婪子表達式裸违,不捕獲掖桦,例如正則:(?>[\d]{1,}),待匹配字符:12345,匹配次數1次,匹配結果是:12345供汛。
(?# ... )注釋
(?= ... )零寬度正預測先行斷言枪汪。匹配...字符前面位置,注意是位置不是字符怔昨,所以寬度為0雀久。例如正則:(?=\d),待匹配字符串:abc123趁舀,匹配的位置是下面字符的前面:1赖捌,2,3
(?! ... )零寬度負預測先行斷言矮烹。匹配后面不是跟著...字符的位置越庇,注意是位置不是字符,所以寬度為0奉狈。例如正則:(?=\d)卤唉,待匹配字符串:abc123,匹配的位置是下面字符的后面:a仁期,b桑驱,c竭恬,iOS匹配時會自動匹配多一個終止符。
(?<= ... )零寬度正回顧后發(fā)斷言熬的。匹配...字符后面位置痊硕,注意是位置不是字符,所以寬度為0押框。例如正則:(?=\d)岔绸,待匹配字符串:abc123,匹配的位置是下面字符的后面:1强戴,2亭螟,3
(?
(?ismwx-ismwx: ... )設置子正則...匹配的flag option挡鞍。例如:待匹配字符串:test骑歹,正則:(?i:TEST),匹配結果:test墨微。正則:(?-i:TEST)道媚,匹配不到。用代碼測試時option不要選NSRegularExpressionCaseInsensitive 翘县。
(?ismwx-ismwx)設置之后位置正則匹配的flag option最域。例如:待匹配字符串:test,正則:(?i)TEST锈麸,匹配結果:test镀脂。正則:(?-i)TEST,匹配不到忘伞,正則:T(?i)EST薄翅,匹配不到,因為前面的T是區(qū)分大小寫的氓奈。用代碼測試時option不要選NSRegularExpressionCaseInsensitive 翘魄。
工具
測試工具多中多樣,可以直接在網上搜索‘正則表達式在線檢測’就會出現一堆(如圖:正則表達式在線檢測.png)
正則表達式在線檢測.png
也可以自己寫代碼進行驗證但是比較麻煩每次都要run舀奶,為了方便于是筆者就自己寫了個簡單的測試用具如果需要的可以點擊iOS正則表達式檢測工具進行下載暑竟。如圖:
iOS正則表達式檢測工具.png
目前沒有做字符串替換功能。
捕獲和不捕獲的區(qū)別
捕獲
捕獲會將當前的匹配到的字符儲存起來育勺,在正則表達式中可以用\n進行使用但荤,n是10進制數,第n個捕獲就寫\n涧至,在替換模式中可以用$n腹躁,表示第n個捕獲的字符串。
不捕獲
不捕獲則不會儲存匹配到的字符串
例子:
//待匹配字符串:hello//正則:(\w)\1//匹配結果:ll//代碼如下:NSString*string = [NSStringstringWithFormat:@"hello"];NSError*error =NULL;NSString*regexString =@"(\\w)\1";NSRegularExpression*regex = [NSRegularExpressionregularExpressionWithPattern:regexString options:NSRegularExpressionUseUnicodeWordBoundarieserror:&error];NSUIntegerinteger = [regex? numberOfMatchesInString:string options:NSMatchingReportProgressrange:NSMakeRange(0, string.length)];NSArray*matches = [regex matchesInString:string? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? options:0range:NSMakeRange(0, [string length])];for(NSTextCheckingResult* resultinmatches) {NSRangematchRange = [result range];NSString* subString = [string substringWithRange:matchRange];NSLog(@"%@",subString);}
//待匹配字符串:hello//正則:(he)((\w)\3)(o)//替換模式:$1-$2-$3-$4//替換結果:he-ll-l-o//捕獲順序說明:根據"("的順序//代碼如下:NSString*string = [NSStringstringWithFormat:@"hello"];NSError*error =NULL;NSString*regexString =@"(he)((\\w)\\3)(o)";NSRegularExpression*regex = [NSRegularExpressionregularExpressionWithPattern:regexString options:NSRegularExpressionUseUnicodeWordBoundarieserror:&error];NSLog(@"%li",regex.numberOfCaptureGroups);NSLog(@"%@",[regex stringByReplacingMatchesInString:string options:NSMatchingReportProgressrange:NSMakeRange(0, string.length) withTemplate:@"$1-$2-$3-$4"]);
Example
1.國內手機號碼
國內手機號碼都是11位化借,開頭大概有:
中國移動:134潜慎、135、136、137铐炫、138垒手、139、150倒信、151科贬、152、157(TD)鳖悠、158榜掌、159、182乘综、183憎账、184、187卡辰、178胞皱、188、147九妈、1705(虛擬運營商移動號段)
中國聯(lián)通:130反砌、131、132萌朱、145(數據卡號段)155宴树、156、176晶疼、185酒贬、186、1709(虛擬運營商聯(lián)通號段)
中國電信:133冒晰、153同衣、177、180壶运、181耐齐、189、134蒋情、1700(虛擬運營商電信號段)
參考百度知道
正則如下:
(134|135|136|137|138|139|150|151|152|157|158|159|182|183|184|187|178|188|147|1705|130|131|132|145|155|156|176|185|186|1709|133|153|177|180|181|189|134|1700)\d{8}
分析:
“(134|135|136|137|138|139|150|151|152|157|158|159|182|183|184|187|178|188|147|1705|130|131|132|145|155|156|176|185|186|1709|133|153|177|180|181|189|134|1700)“匹配的號碼開頭埠况。“\d{8}“匹配后面8個必須是數字
經測試匹配成功棵癣。
2.中文
正則表達式:[\u4E00-\u9FA5]
分析:中文編碼和部分日文編碼在\u4E00-\u9FA5范圍
3.郵箱
A@B.C
規(guī)則如下:
A可以為數字和字母辕翰,且長度至少為1
B可以為數字和字母,且長度至少為1
C為字母或者中文狈谊,長度至少為2喜命。(域名后綴長度為1的沒見過)
正則表達式:\b(?i)\w+@\w+\.[A-Z\u4E00-\u9FA5]{2,}\b
分析:
“\b“是邊界沟沙,表示郵箱前后都是空格或者其他無內容字符“(?i)“表示后面的字母都是不區(qū)分大小寫的“\w+“非字符,長度至少為1“.[A-Z\u4E00-\u9FA5]{2,}“字母或者中文壁榕,長度至少為2
4.國內電話
國內電話的格式是:區(qū)號-號碼
區(qū)號最短3位矛紫,最長4。號碼最短5位牌里,最長8位
正則:[\d]{3,4}-[d]{5,8}
分析:
“[\d]{3,4}“ 數字颊咬,3到4位“-“分割符-“[d]{5,8}“ 數字,5到8位
5.用戶名牡辽,英文開頭喳篇,允許輸入數字和英文
正則:^[A-Za-z][A-Za-z0-9]*
分析:
“^[A-Za-z]“字母開頭“[A-Za-z0-9]*“可以輸入數字和英文
6.QQ號
QQ還最短是5位。
正則:[1-9]\d{4,}
分析:
“[1-9]“開頭是不為0的數字“\d{4,}“至少有4個數字
7.身份證
第二代居民身份證居民身份證編碼規(guī)則如下:
(1)前1态辛、2位數字表示:所在属锢健(直轄市、自治區(qū))的代碼因妙;
(2)第3痰憎、4位數字表示:所在地級市(自治州)的代碼;
(3)第5攀涵、6位數字表示:所在區(qū)(縣、自治縣洽沟、縣級市)的代碼以故;
(4)第7—14位數字表示:出生年、月裆操、日怒详;
(5)第15、16位數字表示:所在地的派出所的代碼踪区;
(6)第17位數字表示性別:奇數表示男性(1昆烁、3、5缎岗、7静尼、9),偶數表示女性(0传泊、2鼠渺、4、6眷细、8)拦盹;
(7)第18位數字是校檢碼:也有的說是個人信息碼,不是隨計算機的隨機產生溪椎,它是 用來檢驗身份證的正確性普舆。校檢碼可以是0—9的數字恬口,有時也用x表示。作為尾號的校驗碼沼侣,是由號碼編制單位按統(tǒng)一的公式計算出來的楷兽,如果某人的尾號是0-9字旭,都不會出現X另假,但如果尾號是10,那么就得用X來代替图仓,因為如果用10做尾號雅潭,那么此人的身份證就變成了19位揭厚。X是羅馬數字的10,用X來代替10扶供,可以保證公民的身份證符合國家標準筛圆。
注意:這里最大能輸入2019年。
正則:[1-6][0-7][\d]{4}((19[\d]{2})|(20[0-1][\d]))((0[1-9])|(1[0-2]))((0[1-9])|([1-2]\d)|(3[0-1]))[\d]{3}[\dx]
分析:
“[1-6][0-7]“根據蚀慌ā(直轄市太援、自治區(qū))的代碼第一位是1-6,第二位是0-7“[\d]{4}“地級市、所在區(qū)編碼都是數字“((19[\d]{2})|(20[0-1][\d]))((0[1-9])|(1[0-2]))((0[1-9])|([1-2]\d)|(3[0-1]))“出生日期扳碍,最早的是1900/01/01提岔,最晚是2019/12/31“[\d]{3}[\dx]“ 四個數字或者3個數字+x
8.郵政編碼
國內郵政編碼為6位數字
正則\d{6}
分析:都是數字
9.網址
正則為:(?i)\b(http://|https://)?([www.]?)[\w\.\-]+\.[A-Z\u4E00-\u9FA5]{2,}(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\;\?\'\\+&%\$#\=~_\-]+))*
能匹配:
http://jianshu.com:8080/http://jianshu.com/?a=asdsa&b=asdashttp://簡書.com/
不能匹配:
ftp://jianshu.comftps://jianshu.com
分析:
"(?i)"不區(qū)分大小寫"\b"邊界"(http://|https://)?"http://或者https://開頭也可以沒有"([www.]?)"www. 可有可無"[\w\.\-]+"可以出現數字、英文笋敞、英文句號碱蒙、-、中文夯巷,至少一個"\.":英文句號."[A-Z\u4E00-\u9FA5]{2,}"英文赛惩,中文至少兩個"(\:[0-9]+)*"\、:趁餐、數字可有可無"(/($|[a-zA-Z0-9\.\,\;\?\'\\\+&;%\$#\=~_\-]+))*"斜杠/后面可以出現的字符
10.出生日期
格式:yyyy/MM/dd
注意:這里最大能輸入2019年喷兼。
正則:((19[\d]{2})|(20[0-1][\d]))/((0[1-9])|(1[0-2]))/((0[1-9])|([1-2]\d)|(3[0-1]))
分析:
"(19[\d]{2})|(20[0-1][\d])"出生年份1900~2019"/"分隔符/"((0[1-9])|(1[0-2]))"出生月份01-12"/"分隔符/"((0[1-9])|([1-2]\d)|(3[0-1]))"出生日期1-31
11.時間
24小時制,時間格式:hh:mm:ss
正則:(([0-1]\d)|(2[0-3])):[0-5]\d:[0-5]\d
分析:
"(([0-1]\d)|(2[0-3]))"00到23小時[0-5]\d""00到59
12.圖片文件名
正則:\w+\.(?i:png|jpg|jpeg|gif)
分析:
"[\w]+"圖片文件名不可以為字符"(?i:png|jpg|jpeg|gif)"后綴名為png后雷、jpg季惯、jpeg、gif中的一種喷面,不區(qū)分大小寫星瘾。
轉載 http://www.reibang.com/p/4eb7e7971146