我們經(jīng)常會(huì)遇到驗(yàn)證一個(gè)用戶的操作數(shù)據(jù)是否合法,我們最好的方式是用正則去檢測用戶的行為操作是否正確
![來個(gè)圖片放松一下啊](http://img5.imgtn.bdimg.com/it/u=1362880611,3519150918&fm=21&gp=0.jpg)
正則匹配整數(shù)和浮點(diǎn)數(shù)
需求:檢測文本中的數(shù)字,并改變顏色凭戴,數(shù)字都是序列化的樣式文本:當(dāng)前已經(jīng)使用的存儲(chǔ)
空間大小為3.2GB,下載文件占用788MB粥庄,還剩余6.7GB空間薯酝,總?cè)萘繛?2GB.
我們需要匹配出來一下幾個(gè)數(shù)字
3.2GB
788MB
6.7GB
12GB
我們?nèi)绻谝谎劭瓷先ツ阌X得要如何去做呢,我們今天要的不僅是匹配母截,還要獲取到對(duì)應(yīng)的數(shù)值
這個(gè)匹配我們使用系統(tǒng)的NSRegularExpression
,進(jìn)行內(nèi)容的匹配到忽,開始我想到了三種規(guī)則:如下
-
\\d*\\.\\d*[M|G]B
這種規(guī)則只適合含有小數(shù)點(diǎn)的數(shù)值,等到項(xiàng)目中用的時(shí)候才發(fā)現(xiàn)整數(shù)沒有匹配上去清寇,繼續(xù)修改下面 -
(((\\d*\\.\\d*)MB)|((\\d*\\.\\d*)GB))
這個(gè)是一位PHP大牛寫的喘漏,我仔細(xì)分解了一下,似乎我寫的那個(gè)就可以了华烟,但是還是匹配到整數(shù)就錯(cuò)誤翩迈。 -
(\\d*(\\.\\d*)?)[M|G]B
這個(gè)才是我們想要的,既能匹配小數(shù)盔夜,又可以匹配整數(shù)负饲,這個(gè)是我考慮之后稍作修改堤魁,檢測結(jié)果是正常的
第三種情況的匹配代碼實(shí)例如下:
NSString *searchText = @"當(dāng)前手機(jī)已使用存儲(chǔ)大小為3.2GB,已下載文件占用899MB返十,剩余空間大小5.8GB妥泉,當(dāng)前總?cè)萘繛?2GB";
NSError *error = NULL;
//@"\\d*\\.\\d*[M|G]B" 匹配字符串中連續(xù)規(guī)則的數(shù)字序列
//@"(((\\d*\\.\\d*)MB)|((\\d*\\.\\d*)GB))" 匹配規(guī)則全部序列
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(\\d*(\\.\\d*)?)[M|G]B"
options:NSRegularExpressionCaseInsensitive error:&error];
NSTextCheckingResult *result = [regex firstMatchInString:searchText options:0 range:NSMakeRange(0, [searchText length])];
NSArray * matches1 = [regex matchesInString:searchText options:NSMatchingReportProgress range:NSMakeRange(0, [searchText length])];
for (NSTextCheckingResult * test in matches1) {
NSString *tagValuestr = [searchText substringWithRange:test.range];
NSLog(@"tagvalue = %@",tagValuestr);
}
if (result) {
NSLog(@"%@", [searchText substringWithRange:result.range]);
}
控制臺(tái)輸出結(jié)果為:
2016-03-15 17:41:19.608 RegularExp[54814:2551313] tagvalue = 3.2GB
2016-03-15 17:41:19.608 RegularExp[54814:2551313] tagvalue = 899MB
2016-03-15 17:41:19.608 RegularExp[54814:2551313] tagvalue = 5.8GB
2016-03-15 17:41:19.608 RegularExp[54814:2551313] tagvalue = 12GB
2016-03-15 17:41:19.609 RegularExp[54814:2551313] 3.2GB
我們可以發(fā)現(xiàn),這個(gè)就是我們想要的結(jié)果
result
是單個(gè)結(jié)果洞坑,使用matches
是獲取多個(gè)結(jié)果
我們再說一下獲取URL參數(shù)的正則
代碼如下:
NSError *error1;
NSString *regTags=[[NSString alloc] initWithFormat:@"(^|&|\\?)+%@=+([^&]*)(&|$)",@"adc"];
NSRegularExpression *regex1 = [NSRegularExpression regularExpressionWithPattern:regTags
options:NSRegularExpressionCaseInsensitive
error:&error1];
// 執(zhí)行匹配的過程
NSString *webaddress=@"http://www.baidu.com/dd/adb.htm?adc=e12&xx=lkw&dalsjd=12";
NSArray *matches = [regex1 matchesInString:webaddress
options:0
range:NSMakeRange(0, [webaddress length])];
for (NSTextCheckingResult *match in matches) {
//NSRange matchRange = [match range];
//NSString *tagString = [webaddress substringWithRange:matchRange]; // 整個(gè)匹配串
// NSRange r1 = [match rangeAtIndex:1];
// if (!NSEqualRanges(r1, NSMakeRange(NSNotFound, 0))) { // 由時(shí)分組1可能沒有找到相應(yīng)的匹配盲链,用這種辦法來判斷
// //NSString *tagName = [webaddress substringWithRange:r1]; // 分組1所對(duì)應(yīng)的串
// return @"";
// }
NSString *tagValue = [webaddress substringWithRange:[match rangeAtIndex:2]]; // 分組2所對(duì)應(yīng)的串
// NSLog(@"分組2所對(duì)應(yīng)的串:%@\n",tagValue);
NSLog(@"tagvalue = %@",tagValue);
}
控制臺(tái)的輸出
2016-03-15 17:41:19.609 RegularExp[54814:2551313] tagvalue = e12
以上是對(duì)NSRegularExpression 這個(gè)類的使用
下面我們擴(kuò)展一些實(shí)用的東西:
方法一、 使用謂詞NSPredicate
創(chuàng)建正則表達(dá)式
一般我們只使用謂詞僅供開發(fā)者判斷用戶輸入的字符串是否合法迟杂,并沒有其他要求
// 編寫正則表達(dá)式:只能是數(shù)字或英文刽沾,或兩者都存在
NSString *regex = @"^[a-z0-9A-Z]*$";
// 創(chuàng)建謂詞對(duì)象并設(shè)定條件的表達(dá)式
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
// 判斷的字符串
NSString *str = @"Hello100";
// 對(duì)字符串進(jìn)行判斷
if ([predicate evaluateWithObject:str]) {
NSLog(@"Match");
}
上面判斷之后的結(jié)果就是會(huì)輸出 Match ,如果我們替換一下字符串為-逢慌、= 悠轩! 之類的,那么判斷就不會(huì)進(jìn)入攻泼。
方法二火架、 通過NSRegularExpression 獲取指定的對(duì)象
我們可以過濾掉一些東西獲取到我們想要的結(jié)果,代碼更清晰:
NSString *url = @"8888@163.com";
NSError *error;
// 創(chuàng)建NSRegularExpression對(duì)象并指定正則表達(dá)式
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:@"[^@]*\\."
options:0
error:&error];
if (!error) { // 如果沒有錯(cuò)誤
// 獲取特特定字符串的范圍
NSTextCheckingResult *match = [regex firstMatchInString:url
options:0
range:NSMakeRange(0, [url length])];
if (match) {
// 截獲特定的字符串
NSString *result = [url substringWithRange:match.range];
NSLog(@"%@",result);
}
} else { // 如果有錯(cuò)誤忙菠,則把錯(cuò)誤打印出來
NSLog(@"error - %@", error);
}
上面這個(gè)列子我們是從特定字符串中檢索以“@”開頭 “.” 結(jié)尾的區(qū)間字符串何鸡,所以最終獲取到的字符串結(jié)尾包括點(diǎn)“.”,最終輸出的是“163.”;
方法三牛欢、NSRegularExpression 獲取多個(gè)結(jié)果骡男,也就是最上面我們的需求
我們講解一個(gè)獲取連續(xù)數(shù)字序列的正則
NSString *regex = @"\\-\\d*\\.";
NSString *str = @"-111.-666.-888.";
NSError *error;
NSRegularExpression *regular = [NSRegularExpression regularExpressionWithPattern:regex
options:NSRegularExpressionCaseInsensitive
error:&error];
// 對(duì)str字符串進(jìn)行匹配
NSArray *matches = [regular matchesInString:str
options:0
range:NSMakeRange(0, str.length)];
// 遍歷匹配后的每一條記錄
for (NSTextCheckingResult *match in matches) {
NSRange range = [match range];
NSString *mStr = [str substringWithRange:range];
NSLog(@"%@", mStr);
}
@"\\-\\d*\\.";
我們這里的規(guī)則是-號(hào)開頭,\ 代表特殊字符轉(zhuǎn)義傍睹,不參與匹配隔盛,“\d” 相當(dāng)于 [0-9] ,有\(zhòng) 開始的規(guī)則,需要加入轉(zhuǎn)義字符“拾稳、”
方法三的輸出結(jié)果是
-111.
-666.
-888.
通過打印結(jié)果吮炕,我們可以得知,我們通過方法三的結(jié)果是多個(gè)访得,獲取到我們想要的結(jié)果龙亲。
注:我們把常用的字符注釋一下
-
“\” :將下一個(gè)字符標(biāo)記為一個(gè)特殊字符、或一個(gè)原義字符悍抑、或者一個(gè)向后引用鳄炉,或者一個(gè)八進(jìn)制轉(zhuǎn)義符。例如:“\\n”匹配“\n” "\n"搜骡。序列“\\” 匹配“\” 而 “\(” 匹配“(”
拂盯。 "^": 匹配輸入字符串的開始位置,如果設(shè)置了RegExp對(duì)象的Multiline屬性记靡,^也匹配“\n”或“\r”之后的位置磕仅。
"$" : 匹配輸入字符串的結(jié)束位置珊豹。如果設(shè)置了RegExp對(duì)象的Multiline屬性,$也匹配“\n”或“\r”之前的位置榕订。
"*": 匹配前面的子表達(dá)式零次或多次(大于等于0次)店茶。例如,zo*能匹配“z”劫恒,“zo”以及“zoo”贩幻。*等價(jià)于{0,}。
"+":匹配前面的子表達(dá)式一次或多次(大于等于1次)两嘴。例如丛楚,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”憔辫。+等價(jià)于{1,}趣些。
"?": 匹配前面的子表達(dá)式零次或一次。例如贰您,“do(es)?”可以匹配“do”或“does”中的“do”坏平。?等價(jià)于{0,1}。
"{n}":n是一個(gè)非負(fù)整數(shù)锦亦。匹配確定的n次舶替。例如,“o{2}”不能匹配“Bob”中的“o”杠园,但是能匹配“food”中的兩個(gè)o顾瞪。
"{n,}":n是一個(gè)非負(fù)整數(shù)。至少匹配n次抛蚁。例如陈醒,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o瞧甩《危“o{1,}”等價(jià)于“o+”∏着洌“o{0,}”則等價(jià)于“o*”尘应。
"{n,m}":m和n均為非負(fù)整數(shù)惶凝,其中n<=m吼虎。最少匹配n次且最多匹配m次。例如苍鲜,“o{1,3}”將匹配“fooooood”中的前三個(gè)o思灰。“o{0,1}”等價(jià)于“o?”混滔。請(qǐng)注意在逗號(hào)和兩個(gè)數(shù)之間不能有空格洒疚。
"?":當(dāng)該字符緊跟在任何一個(gè)其他限制符(*,+,?歹颓,{n},{n,}油湖,{n,m})后面時(shí)巍扛,匹配模式是非貪婪的。非貪婪模式盡可能少的匹配所搜索的字符串乏德,而默認(rèn)的貪婪模式則盡可能多的匹配所搜索的字符串撤奸。例如,對(duì)于字符串“oooo”喊括,“o+?”將匹配單個(gè)“o”胧瓜,而“o+”將匹配所有“o”。
".":匹配除“\r\n”之外的任何單個(gè)字符郑什。要匹配包括“\r\n”在內(nèi)的任何字符府喳,請(qǐng)使用像“[\s\S]”的模式。
"\s" :"匹配任何空白字符蘑拯,包括空格钝满、制表符、換頁符等等强胰。等價(jià)于[ \f\n\r\t\v]舱沧。"
正則先說到這里,請(qǐng)查看鏈接:正則使用說明