iOS中的正則表達式

正則表達式也用過一段時間了,不同的語言中用起來并不相同,這里姑且做為iOS正則的一個總結(jié)貼。

[TOC]

iOS中的正則表達式

正則語法

1. 基本

我把同類正則符號做了分組列舉,以/作為分隔

元字符 描述
\ 轉(zhuǎn)義符 如\\n為\n,單\n為換行符
^ / $ 行首與行尾
? / * / + / {n} / {m,n} 零次或一次/>=0次/>=1次/n次/m-n次,mn可省略一端限制
? 跟在(*,+,?,{n},{n,},{n,m})后面時,為非貪婪模式。如,對于“oooo”,o+得到oooo,o+?得到o
x|y 匹配x或y
&& 字符組與運算,有些語言支持,比如&&+[] Java中就支持,但JavaScript不支持。驗證iOS中支持。
[xyz1-9] 匹配xyz或者1-9數(shù)字其中一個
[^xyz] 非xyz
\b / \B 單詞/非單詞的邊界,可放前后。如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”
\d / \D 數(shù)字/非數(shù)字
\s / \S 不可見/可見字符。\s不可見,等價于[ \f\n\r\t\v]
\w / \W \w包括下劃線的字符,包括字母/數(shù)字/中文/下劃線,不包括emoj。
. 匹配任何單個字符(注意不包括換行符)

1.1 &&+[]運算

對于&&+[]運算符,原話是這樣描述的:

有些語言支持,比如&&+[] Java中就支持,但JavaScript不支持。
示例7:匹配英文字母中除去元音字符的字符
[[a-z]&&[^aeiou]] // a-z 且排除掉5個元音字符aeiou

我的驗證,iOS中是支持的。

NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @"[[a-z ]&&[^acdkn]]+"];
NSLog(@"測試&&:%d", [predicate1 evaluateWithObject:@"better boy"]);
NSLog(@"測試&&:%d", [predicate1 evaluateWithObject:@"better boy run"]);

NSPredicate *predicate11 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @"[1234567890&&[^6]]+"];
NSLog(@"測試&&:%d", [predicate11 evaluateWithObject:@"1234567890"]);
NSLog(@"測試&&:%d", [predicate11 evaluateWithObject:@"123457890"]);
/*打印結(jié)果:
2018-10-11 14:15:03.206346+0800 WEEX_TEST[96757:22569846] 測試&&:1
2018-10-11 14:15:03.206425+0800 WEEX_TEST[96757:22569846] 測試&&:0
2018-10-11 14:15:03.206534+0800 WEEX_TEST[96757:22569846] 測試&&:0
2018-10-11 14:15:03.206600+0800 WEEX_TEST[96757:22569846] 測試&&:1
*/

2. 進階

元字符 描述
\f/\n/\r/\t/\v 換頁符/換行符/回車符/制表符/垂直制表符
\xn 十六進制轉(zhuǎn)義值,可表示ASCII編碼。如:“\x41”匹配“A”。
\un 四個十六進制數(shù)字表示的Unicode字符。如,\u00A9
\n 標識一個八進制轉(zhuǎn)義值或引用。注:引用優(yōu)先于轉(zhuǎn)義,如前面不足n個表達式,才轉(zhuǎn)義生效。
\num 對所獲取的匹配的引用。例如,"78aaa",用@"(.)\\1",得到"aa"。????456678aa87aaaas,用@"(\d)(\d)(\w)\3\2\1",得到"78aa87"。注:引用優(yōu)先于轉(zhuǎn)義,如前面不足n個表達式,才轉(zhuǎn)義生效。

3. 非獲取匹配

非獲取匹配,匹配pattern但不獲取匹配結(jié)果.

元字符 描述
?:pattern 例如“industr(?:y|ies)”就是一個比“industry|industries”更簡略的表達式。
?=pattern 正向肯定預(yù)查.
?<=pattern 反向肯定預(yù)查.
?!pattern 正向否定預(yù)查.
?<!pattern 反向否定預(yù)查.

其中,包含了4個概念:

  • 正向 --> 在查找目標右側(cè)
  • 反向 --> 在查找目標左側(cè)
  • 肯定 --> 是pattern
  • 否定 --> 不是pattern

正常讀起來就是:

  • 正向肯定預(yù)查:在目標右側(cè)是pattern
  • 反向肯定預(yù)查:在目標左側(cè)是pattern
  • 正向否定預(yù)查:在目標右側(cè)不是pattern
  • 反向否定預(yù)查:在目標左側(cè)不是pattern

<span id = "jump_find_emoji_code"></span>
來個例子,查找中括號內(nèi)的emoji表情,但不要中括號

//用到了:正向肯定預(yù)查?=與反向肯定預(yù)查?<=
NSString *sourceStr3 = @"我是一個[笑臉],[強],你是一個[自信]";
NSString *pattern = @"(?<=\\[).*?(?=\\])";
NSRegularExpression *regex3 = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil];
NSArray<NSTextCheckingResult *> *results3 = [regex3 matchesInString:sourceStr3 options:NSMatchingReportProgress range:NSMakeRange(0, sourceStr3.length)];
for (NSTextCheckingResult *result in results3) {
    NSLog(@"中括號內(nèi):%@", [sourceStr3 substringWithRange:result.range]);
}
/*打印結(jié)果:
2018-10-10 16:08:35.145447+0800 WEEX_TEST[15000:20387096] 中括號內(nèi):笑臉
2018-10-10 16:08:35.145550+0800 WEEX_TEST[15000:20387096] 中括號內(nèi):強
2018-10-10 16:08:35.145652+0800 WEEX_TEST[15000:20387096] 中括號內(nèi):自信
*/

分解:

(?<=\\[)    //目標左側(cè)是[
.*          //查找任意數(shù)量的任意字符,也是我們想查詢的目標
?           //非貪婪。如果去掉?,會得到:笑臉],[強],你是一個[自信
(?=\\])     //目標右側(cè)是]

升級一下:如果需求emoji表情為兩個字,如何丟棄一個字的emoji呢?如果有些干擾的或者一半的中括號,如何規(guī)避掉呢?

NSString *sourceStr3 = @"我是一個[笑臉],[[強]],][][[∑??]你是一個[自信]";
NSString *pattern = @"(?<=\\[)([^\\[\\]]{2,}?)(?=\\])";
NSRegularExpression *regex3 = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil];
NSArray<NSTextCheckingResult *> *results3 = [regex3 matchesInString:sourceStr3 options:NSMatchingReportProgress range:NSMakeRange(0, sourceStr3.length)];
for (NSTextCheckingResult *result in results3) {
    NSLog(@"中括號內(nèi):%@", [sourceStr3 substringWithRange:result.range]);
}
/*打印結(jié)果:
2018-10-10 16:52:30.027836+0800 WEEX_TEST[27737:20549839] 中括號內(nèi):笑臉
2018-10-10 16:52:30.027931+0800 WEEX_TEST[27737:20549839] 中括號內(nèi):∑??
2018-10-10 16:52:30.027984+0800 WEEX_TEST[27737:20549839] 中括號內(nèi):自信
*/

用到了[^]符號,去否定[];用到了{2,},去匹配兩位以上。其實{2,}后面的那個非貪婪?也可以去掉的,因為碰到[]就匹配結(jié)束了,不會出現(xiàn)貪婪∑??]你是一個[自信進來的情況。

iOS中正則的三種表現(xiàn)形式

  1. [string rangeOfString: options:]查找字符串范圍,返回第一個匹配成功的range
  2. NSPredicate謂詞匹配數(shù)組與字符串。
  3. NSRegularExpression匹配。

1. [string rangeOfString: options:]

例查找第一個出現(xiàn)的數(shù)字:

    NSString *sourceStr2 = @"123元45678秒09分";
    NSString *regex2 = @"(?<=“).*(?=”)";
    NSRange range2 = [sourceStr2 rangeOfString:regex2 options:NSRegularExpressionSearch];
    if (range2.length > 0) {
        NSLog(@"%@", [sourceStr2 substringWithRange:range2]);
    }
    //打?。?23

1.1 出現(xiàn)的option參數(shù)

typedef NS_OPTIONS(NSUInteger, NSStringCompareOptions) {
    NSCaseInsensitiveSearch = 1,  //不區(qū)分大小寫比較
    NSLiteralSearch = 2,       //逐字節(jié)比較 區(qū)分大小寫
    NSBackwardsSearch = 4,     //從字符串末尾開始搜索
    NSAnchoredSearch = 8,      //搜索限制范圍的字符串
    NSNumericSearch = 64,     //按照字符串里的數(shù)字為依據(jù),算出順序。例如 Foo2.txt < Foo7.txt < Foo25.txt
    NSDiacriticInsensitiveSearch    NS_ENUM_AVAILABLE(10_5, 2_0) = 128,//忽略 "-" 符號的比較
    NSWidthInsensitiveSearch    NS_ENUM_AVAILABLE(10_5, 2_0) = 256,//忽略字符串的長度,比較出結(jié)果
    NSForcedOrderingSearch  NS_ENUM_AVAILABLE(10_5, 2_0) = 512,//忽略不區(qū)分大小寫比較的選項,并強制返回 NSOrderedAscending 或者 NSOrderedDescending
    NSRegularExpressionSearch   NS_ENUM_AVAILABLE(10_7, 3_2) = 1024    /*只能應(yīng)用于 rangeOfString:..., stringByReplacingOccurrencesOfString:...和 replaceOccurrencesOfString:... 方法。
    使用通用兼容的比較方法,如果設(shè)置此項,可以去掉 NSCaseInsensitiveSearch 和 NSAnchoredSearch*/
};

2. NSPredicate

==NSPredicate下,例子引自: sunny_zl==

其中,只有MATCHES時為正則匹配,這兒也把NSPredicate用法羅列下。

2.1 比較運算符

包括:

1. >=
2. <=
3. >
4. <
5. !=
6. ==
7. BETWEEN {下限,上限} //大于或等于下限

例:

NSNumber *testNumber = @123;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF = 123"];
if ([predicate evaluateWithObject:testNumber]) {
    NSLog(@"testString:%@", testNumber);
}
//結(jié)果:testString:123

2.2 邏輯運算符

包括:

1. AND &&
2. OR ||
3. NOT !

例:

NSArray *testArray = @[@1, @2, @3, @4, @5, @6];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF > 2 && SELF < 5"];
NSArray *filterArray = [testArray filteredArrayUsingPredicate:predicate];
NSLog(@"filterArray:%@", filterArray);
//結(jié)果為:(3, 4)

2.3 字符串比較運算符

包括:

1. BEGINSWITH   //以指定的字符串開頭
2. ENDSWITH     //以指定的字符串結(jié)尾
3. CONTAINS     //包含指定的字符串
4. LIKE         //是否匹配指定的字符串模板。?代表一個字符和*代表任意多個字符。如:name LIKE '*ac*'中間包含ac;name LIKE '?ac*'匹配第2個位置開始為ac
5. MATCHES      //匹配指定的正則表達式

注:字符串比較都是區(qū)分大小寫和重音符號的。
如:cafécafe是不一樣的,Cafecafe也是不一樣的。

cd符號:[c]是不區(qū)分大小寫,[d]是不區(qū)分重音符號。如:name LIKE[cd] 'cafe'

如:

//簡單判斷是否手機號
- (BOOL)checkPhoneNumber:(NSString *)phoneNumber {
    NSString *regex = @"^[1][3-8]\\d{9}$";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    return [pred evaluateWithObject:phoneNumber];
}

2.4 集合運算符

包括:

1. ANY、SOME:集合中任意一個元素滿足條件,就返回YES。
2. ALL:集合中所有元素都滿足條件,才返回YES。
3. NONE:集合中沒有任何元素滿足條件就返回YES。如:NONE person.age < 18
4. IN只有當左邊表達式或值出現(xiàn)在右邊的集合中才會返回YES。

如:

//查找不在filterArray中元素
NSArray *filterArray = @[@"ab", @"abc"];
NSArray *array = @[@"a", @"ab", @"abc", @"abcd"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)", filterArray];
NSLog(@"%@", [array filteredArrayUsingPredicate:predicate]);
//輸出:( a, abcd )

2.5 謂詞中使用占位符參數(shù)

包括:

%K:用于動態(tài)傳入屬性名
%@:用于動態(tài)設(shè)置屬性值
$VALUE: 使用動態(tài)改變的屬性值

如:

//定義一個property來存放屬性名,定義一個value來存放值
NSString *property = @"name";
NSString *value = @"Jack";
//該謂詞的作用是如果元素中property屬性含有值value時就取出放入新的數(shù)組內(nèi),這里是name包含Jack
NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K CONTAINS %@", property, value];
NSArray *newArray = [array filteredArrayUsingPredicate:pred];
NSLog(@"newArray:%@", newArray);

//------------- 傳遞VALUE值 -------------
// 創(chuàng)建謂詞,屬性名改為age,要求這個age包含$VALUE字符串,子謂詞傳遞value值
NSPredicate *predTemp = [NSPredicate predicateWithFormat:@"%K > $VALUE", @"age"];
// 指定$VALUE的值為 25
NSPredicate *pred1 = [predTemp predicateWithSubstitutionVariables:@{@"VALUE" : @25}];
NSArray *newArray1 = [array filteredArrayUsingPredicate:pred1];
NSLog(@"newArray1:%@", newArray1);

2.6 基本用法

//字符串內(nèi)查找 查找數(shù)字
NSString *regex = @"\d";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
BOOL match = [predicate evaluateWithObject:sourceString];

//數(shù)字比較 判斷是否100-200間
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF BETWEEN {100, 200}"];

//過濾數(shù)組內(nèi)字符串 在filterArray中
NSArray *filterArray = @[@"ab", @"abc"];
NSArray *array = @[@"a", @"ab", @"abc", @"abcd"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF IN %@", filterArray];
NSArray *newArray = [array filteredArrayUsingPredicate:predicate];

//過濾數(shù)組內(nèi)字典 查找name張姓的
NSArray *array = @[@{@"name" : @"zhangsan", @"age" : @"10"},
                   @{@"name" : @"lisi",     @"age" : @"11"},
                   @{@"name" : @"wangwu",   @"age" : @"12"}];
 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name CONTAINS[c] 'zhang'"];
NSArray *results = [array filteredArrayUsingPredicate:predicate];

//過濾數(shù)組內(nèi)對象,同數(shù)組內(nèi)字典,不再舉例

//對象的key比較 對象的age大于25
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age > 25"];

3. NSRegularExpression

3.1 查找匹配

1. 查找第一個匹配范圍。 
- (NSRange)rangeOfFirstMatchInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;

2. 查找第一個匹配結(jié)果。
- (nullable NSTextCheckingResult *)firstMatchInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;

3. 查找滿足條件總次數(shù)。
- (NSUInteger)numberOfMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;

4. 查找所有匹配結(jié)果。
- (NSArray<NSTextCheckingResult *> *)matchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;

5. 查找并通過block遍歷結(jié)果。
- (void)enumerateMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range usingBlock:(void (NS_NOESCAPE ^)(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL *stop))block;

還發(fā)現(xiàn)了一個方法:+ (NSString *)escapedPatternForString:(NSString *)string;,這家伙是用來做什么的呢?它是幫助我們添加轉(zhuǎn)義符的!

如:

NSString *ttt = @"\\d{4,}\n";
NSLog(@"%@", ttt);
NSLog(@"%@", [NSRegularExpression escapedPatternForString:ttt]);
/*打印結(jié)果:
2018-10-10 17:25:16.870223+0800 WEEX_TEST[37135:20678832] \d{4,}
2018-10-10 17:25:16.870438+0800 WEEX_TEST[37135:20678832] \\d\{4,\}
*/

3.2 查找替換

1. 字符串替換,返回一個新串
- (NSString *)stringByReplacingMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range withTemplate:(NSString *)templ;

2. 可變字符串替換,返回操作次數(shù)
- (NSUInteger)replaceMatchesInString:(NSMutableString *)string options:(NSMatchingOptions)options range:(NSRange)range withTemplate:(NSString *)templ;

3. 自定義替換功能(沒搞懂,用了后沒發(fā)現(xiàn)什么作用)
- (NSString *)replacementStringForResult:(NSTextCheckingResult *)result inString:(NSString *)string offset:(NSInteger)offset template:(NSString *)templ;

4. 轉(zhuǎn)換為正則表達式字符串
+ (NSString *)escapedTemplateForString:(NSString *)string;

例子1,查找并替換數(shù)字:

NSString *sourceStr = @"123元45678秒09分";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\d+" options:NSRegularExpressionCaseInsensitive error:nil];
NSArray<NSTextCheckingResult *> *results = [regex matchesInString:sourceStr options:NSMatchingReportProgress range:NSMakeRange(0, sourceStr.length)];
for (NSTextCheckingResult *result in results) {
    NSLog(@"%@", [sourceStr substringWithRange:result.range]);
}
    
NSString *replaced = [regex stringByReplacingMatchesInString:sourceStr options:NSMatchingReportProgress range:NSMakeRange(0, sourceStr.length) withTemplate:@"<<-->>"];
NSLog(@"replaced:%@", replaced);
/*打印結(jié)果:
2018-10-10 17:40:30.122470+0800 WEEX_TEST[41545:20749671] 123
2018-10-10 17:40:30.122601+0800 WEEX_TEST[41545:20749671] 45678
2018-10-10 17:40:30.122712+0800 WEEX_TEST[41545:20749671] 09
2018-10-10 17:40:30.122858+0800 WEEX_TEST[41545:20749671] replaced:<<-->>元<<-->>秒<<-->>分
*/

例子2,可變字符串查找并替換

NSMutableString *sourceStr2 = [@"123元45678秒09分" mutableCopy];
NSInteger replaceNum = [regex replaceMatchesInString:sourceStr2 options:NSMatchingReportProgress range:NSMakeRange(0, sourceStr.length) withTemplate:@"<<-->>"];
NSLog(@"replaceNum:%ld replaced:%@", replaceNum, sourceStr2);
/*打印結(jié)果:
2018-10-10 17:45:56.019120+0800 WEEX_TEST[43137:20772997] replaceNum:3 replaced:<<-->>元<<-->>秒<<-->>分
*/

3.3 出現(xiàn)的option參數(shù)

以下說明引自:roc_lei

NSRegularExpressionOptions:

typedef NS_OPTIONS(NSUInteger, NSRegularExpressionOptions) {
   NSRegularExpressionCaseInsensitive             = 1 << 0,     /*不區(qū)分字母大小寫的模式*/
   NSRegularExpressionAllowCommentsAndWhitespace  = 1 << 1,     /*忽略掉正則表達式中的空格和#號之后的字符*/
   NSRegularExpressionIgnoreMetacharacters        = 1 << 2,     /*將正則表達式整體作為字符串處理*/
   NSRegularExpressionDotMatchesLineSeparators    = 1 << 3,     /*允許.匹配任何字符,包括換行符 */
   NSRegularExpressionAnchorsMatchLines           = 1 << 4,     /*允許^和$符號匹配行的開頭和結(jié)尾*/
   NSRegularExpressionUseUnixLineSeparators       = 1 << 5,     /*設(shè)置\n為唯一的行分隔符*/
   NSRegularExpressionUseUnicodeWordBoundaries    = 1 << 6      /*使用Unicode TR#29標準作為詞的邊界,否則所有傳統(tǒng)正則表達式的詞邊界都有效*/
};

NSMatchingOptions:

typedef NS_OPTIONS(NSUInteger, NSMatchingOptions) {
   NSMatchingReportProgress         = 1 << 0, //找到最長的匹配字符串后調(diào)用block回調(diào)
   NSMatchingReportCompletion       = 1 << 1, //找到任何一個匹配串后都回調(diào)一次block
   NSMatchingAnchored               = 1 << 2, //從匹配范圍的開始處進行匹配
   NSMatchingWithTransparentBounds  = 1 << 3, //允許匹配的范圍超出設(shè)置的范圍
   NSMatchingWithoutAnchoringBounds = 1 << 4  //禁止^和$自動匹配行還是和結(jié)束
};

NSMatchingFlags:

typedef NS_OPTIONS(NSUInteger, NSMatchingFlags) {
   NSMatchingProgress               = 1 << 0, //匹配到最長串后被設(shè)置     
   NSMatchingCompleted              = 1 << 1, //全部分配完成后被設(shè)置    
   NSMatchingHitEnd                 = 1 << 2, //匹配到設(shè)置范圍的末尾時被設(shè)置   
   NSMatchingRequiredEnd            = 1 << 3, //當前匹配到的字符串在匹配范圍的末尾時被設(shè)置     
   NSMatchingInternalError          = 1 << 4  //由于錯誤導(dǎo)致的匹配失敗時被設(shè)置   
};

iOS中正則使用實例

一般使用場景分為兩種,全匹配與輸入框內(nèi)邊輸入邊匹配。
實例這里,只演示簡單正則使用規(guī)則,不做完全嚴格的匹配。

1. 全匹配

1.1 是否有效身份證號

//15或18位身份證:第一位為1-9,中間13或16位數(shù)字,最后一位為0-9xX
BOOL validateIdentityCard(NSString *identityCard){
    NSString *regex2 = @"^[1-9](\\d{13}|\\d{16})[0-9xX]$";
    NSPredicate *identityCardPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex2];
    return [identityCardPredicate evaluateWithObject:identityCard];
}

1.2 是否有效手機號

BOOL validatePhoneNumber(NSString *phone) {
    NSString *regex = @"^1[34578]\\d{9}$";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
    return [predicate evaluateWithObject:phone];
}

1.3 是否有效6-16位密碼

//6-16位密碼,只允許輸入大小寫與數(shù)字,并且大小寫與數(shù)字至少每種一個
BOOL validatePWD(NSString *pwd) {
    NSString *regex = @"^(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])[a-zA-Z0-9]{6,16}$";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
    return [predicate evaluateWithObject:pwd];
}

1.4 金額數(shù)字添加逗號分隔符

NSString *sourceText = @"1234567890";
NSString *pattern3 = @"\\B(?=(?:\\d{3})+(?!\\d))";
NSRegularExpression *regex3 = [NSRegularExpression regularExpressionWithPattern:pattern3 options:NSRegularExpressionCaseInsensitive error:nil];
NSArray<NSTextCheckingResult *> *results3 = [regex3 matchesInString:sourceText options:NSMatchingReportProgress range:NSMakeRange(0, sourceText.length)];
NSString *replaced = [regex3 stringByReplacingMatchesInString:sourceText options:NSMatchingReportProgress range:NSMakeRange(0, sourceText.length) withTemplate:@","];
NSLog(@"replaced:%@", replaced);
/*打印結(jié)果:
2018-10-11 10:52:32.896514+0800 WEEX_TEST[38772:22081217] replaced:1,234,567,890
*/

1.5 查找中括號內(nèi)emoji表情

見<a href="#jump_find_emoji_code" target="_self">非獲取匹配中的查找emoji</a>

1.6 限最多8位金額,最多兩位小數(shù),第一位不能為.

//控制8位金額,最多兩位小數(shù),只能輸入數(shù)字與.,第一位不能為.或+-
NSString *toString = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSString *stringRegex = @"(([0]|(0[.]\\d{0,2}))|([1-9]\\d{0,7}(([.]\\d{0,2})?)))?";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", stringRegex];
if ([predicate evaluateWithObject:toString]) {
    return YES;
}
return NO;

2. 邊輸入邊匹配

邊輸入邊匹配的場景還是挺多的,比如限制輸入框輸入手機號碼,輸入金額,輸入密碼,或輸入身份證號。

它與全匹配不同,需要在輸入過程中,邊輸入邊驗證。當檢測到不匹配時,拒絕用戶輸入,所以用:-textField:shouldChangeCharactersInRange:replacementString:。還要支持回車,退格等。注意:正則檢測的是替換后的string。

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    //過濾字符
    if ([string isEqualToString:@""] ||    //按退格可以改變
        [string isEqualToString:@"\n"]) {  //按回車可以改變
        return YES;
    }
    //因為要匹配的是輸入后字符,所以需要替換操作toString
    NSString *toString = [textField.text stringByReplacingCharactersInRange:range withString:string];
    //正則檢測
    NSString *stringRegex = @"(([0]|(0[.]\\d{0,2}))|([1-9]\\d{0,7}(([.]\\d{0,2})?)))?";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", stringRegex];
    if ([predicate evaluateWithObject:toString]) {
        return YES;
    }
    return NO;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • 最近手上要求匹配日語各種片假名平假名的半角全角,第一次弄這個,各種尷尬,在網(wǎng)上查閱了很多資料,不忙了總結(jié)一下,還望...
    小小小小小小米閱讀 972評論 0 1
  • 轉(zhuǎn)自:http://www.aichengxu.com/ios/317295.htm 一、什么是正則表達式正則表達...
    王小賤吖閱讀 519評論 0 2
  • sunshine大姐,呆萌二姐和歡脫小妹在寒假后又一次開始愛的團契啦! 寒假的爭戰(zhàn)把我們傷得滿臉爆痘(當然是我啦)...
    Eelayne閱讀 148評論 2 1
  • 聽劉老師講課,說到遇事憋三秒。當時覺得是一種處理問題的態(tài)度,感觸不深。今天中午,我忙伙了半天燜的小仔雞,炒的莧菜,...
    北方人_4bf2閱讀 259評論 0 1
  • 成功在于積極、主動和熱忱。中國是詩的國度,人們愛用古詩來抒發(fā)自己的理想和抱負。如:“欲窮千里目,更上一層樓?!本秃?..
    金戈舞閱讀 990評論 0 1

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