IOS 正则表达式(NSPredicate的使用)

一般来说这种情况还是蛮多的,比如你从文件中读入了一个array1,然后想把程序中的一个array2中符合array1中内容的元素过滤出来。

正 常傻瓜一点就是两个for循环,一个一个进行比较,这样效率不高,而且代码也不好看。

其实一个循环或者无需循环就可以搞定了,那就需要用搞 NSPredicate这个类了~膜拜此类~

1)例子一,一个循环

NSArray *arrayFilter = [NSArray arrayWithObjects:@"pict", @"blackrain", @"ip", nil];

NSArray *arrayContents = [NSArray arrayWithObjects:@"I am a picture.", @"I am a guy", @"I am gagaga", @"ipad", @"iphone", nil];

我想过滤arrayContents的话只要循环 arrayFilter就好了

int i = 0, count = [arrayFilter count];

for(i = 0; i < count; i ++)

{

NSString *arrayItem = (NSString *)[arrayFilter objectAtIndex:i];

NSPredicate *filterPredicate = [[NSPredicate predicateWithFormat:@"SELF CONTAINS %@", arrayItem];

NSLog(@"Filtered array with filter %@, %@", arrayItem, [arrayContents filteredArrayUsingPredicate:filterPredicate]);

}

当然以上代码中arrayContent最好用mutable 的,这样就可以直接filter了,NSArray是不可修改的。

2)例子二,无需循环

NSArray *arrayFilter = [NSArray arrayWithObjects:@"abc1", @"abc2", nil];

NSArray *arrayContent = [NSArray arrayWithObjects:@"a1", @"abc1", @"abc4", @"abc2", nil];

NSPredicate *thePredicate = [NSPredicate predicateWithFormat:@"NOT (SELF in %@)", arrayFilter];

[arrayContent filterUsingPredicate:thePredicate];


这样arrayContent过滤出来的就是不包含 arrayFilter中的所有item了。


3)生成文件路径下文件集合列表

NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *defaultPath = [[NSBundle mainBundle] resourcePath];
    NSError *error;
    NSArray *directoryContents = [fileManager contentsOfDirectoryAtPath:defaultPath error:&error]


4)match的用法

1. 简单比较

    NSString *match = @"imagexyz-999.png";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF == %@", match];
    NSArray *results = [directoryContents filteredArrayUsingPredicate:predicate];
 
2. match里like的用法(类似Sql中的用法)

  NSString *match = @"imagexyz*.png";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF like %@", match];
    NSArray *results = [directoryContents filteredArrayUsingPredicate:predicate];
3. 大小写比较
  [c]表示忽略大小写,[d]表示忽略重音,可以在一起使用,如下:

NSString *match = @"imagexyz*.png";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF like[cd] %@", match];
    NSArray *results = [directoryContents filteredArrayUsingPredicate:predicate];

4.使用正则 

NSString *match = @"imagexyz-\\d{3}\\.png";  //imagexyz-123.png
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF matches %@", match];
    NSArray *results = [directoryContents filteredArrayUsingPredicate:predicate];


总结:

1) 当使用聚合类的操作符时是可以不需要循环的

2)当使用单个比较类的操作符时可以一个循环来搞定

PS,例子 一中尝试使用[@"SELF CONTAINS %@", arrayFilter] 来过滤会挂调,因为CONTAINS时字符串比较操作符,不是集合操作符。



_————————————————————————————————————————

简述:Cocoa框架中的NSPredicate用于查询,原理和用法都类似于SQL中的where,作用相当于数据库的过滤取。

定义(最常用到的方法):

[objc] view plain copy 派生到我的代码片
  1. NSPredicate*ca=[NSPredicatepredicateWithFormat:(NSString*),...];

Format:
(1)比较运算符>,<,==,>=,<=,!=
可用于数值及字符串
例:@"number > 100"


(2)范围运算符:IN、BETWEEN
例:@"number BETWEEN {1,5}"
@"address IN {'shanghai','beijing'}"


(3)字符串本身:SELF
例:@“SELF == ‘APPLE’"


(4)字符串相关:BEGINSWITH、ENDSWITH、CONTAINS
例:@"name CONTAIN[cd] 'ang'" //包含某个字符串
@"name BEGINSWITH[c] 'sh'" //以某个字符串开头
@"name ENDSWITH[d] 'ang'" //以某个字符串结束
注:[c]不区分大小写[d]不区分发音符号即没有重音符号[cd]既不区分大小写,也不区分发音符号。


(5)通配符:LIKE
例:@"name LIKE[cd] '*er*'" //*代表通配符,Like也接受[cd].
@"name LIKE[cd] '???er*'"


(6)正则表达式:MATCHES
例:NSString *regex = @"^A.+e$"; //以A开头,e结尾
@"name MATCHES %@",regex


实际应用:
(1)对NSArray进行过滤

[objc] view plain copy 派生到我的代码片
  1. NSArray*array=[[NSArrayalloc]initWithObjects:@"beijing",@"shanghai",@"guangzou",@"wuhan",nilnil];
  2. NSString*string=@"ang";
  3. NSPredicate*pred=[NSPredicatepredicateWithFormat:@"SELFCONTAINS%@",string];
  4. NSLog(@"%@",[arrayfilteredArrayUsingPredicate:pred]);


(2)判断字符串首字母是否为字母:

[objc] view plain copy 派生到我的代码片
  1. NSString*regex=@"[A-Za-z]+";
  2. NSPredicate*predicate=[NSPredicatepredicateWithFormat:@"SELFMATCHES%@",regex];
  3. if([predicateevaluateWithObject:aString]){
  4. }


(3)字符串替换:

[objc] view plain copy 派生到我的代码片
  1. NSError*error=NULL;
  2. NSRegularExpression*regex=[NSRegularExpressionregularExpressionWithPattern:@"(encoding=\")[^\"]+(\")"
  3. options:0
  4. error:&error];
  5. NSString*sample=@"<xmlencoding=\"abc\"></xml><xmlencoding=\"def\"></xml><xmlencoding=\"ttt\"></xml>";
  6. NSLog(@"Start:%@",sample);
  7. NSString*result=[regexstringByReplacingMatchesInString:sample
  8. options:0
  9. range:NSMakeRange(0,sample.length)
  10. withTemplate:@"$1utf-8$2"];
  11. NSLog(@"Result:%@",result);


(4)截取字符串:

[objc] view plain copy 派生到我的代码片
  1. //组装一个字符串,需要把里面的网址解析出来
  2. NSString*urlString=@"<meta/><link/><title>1Q84BOOK1</title></head><body>";
  3. //NSRegularExpression类里面调用表达的方法需要传递一个NSError的参数。下面定义一个
  4. NSError*error;
  5. //http+:[^\\s]*这个表达式是检测一个网址的。(?<=title\>).*(?=</title)截取html文章中的<title></title>中内文字的正则表达式
  6. NSRegularExpression*regex=[NSRegularExpressionregularExpressionWithPattern:@"(?<=title\\>).*(?=</title)"options:0error:&error];
  7. if(regex!=nil){
  8. NSTextCheckingResult*firstMatch=[regexfirstMatchInString:urlStringoptions:0range:NSMakeRange(0,[urlStringlength])];
  9. if(firstMatch){
  10. NSRangeresultRange=[firstMatchrangeAtIndex:0];
  11. //从urlString当中截取数据
  12. NSString*result=[urlStringsubstringWithRange:resultRange];
  13. //输出结果
  14. NSLog(@"->%@<-",result);
  15. }
  16. }


(5)判断手机号码,电话号码函数

[objc] view plain copy 派生到我的代码片
  1. //正则判断手机号码地址格式
  2. -(BOOL)isMobileNumber:(NSString*)mobileNum
  3. {
  4. /**
  5. *手机号码
  6. *移动:134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
  7. *联通:130,131,132,152,155,156,185,186
  8. *电信:133,1349,153,180,189
  9. */
  10. NSString*MOBILE=@"^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$";
  11. /**
  12. *中国移动:ChinaMobile
  13. *134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
  14. */
  15. NSString*CM=@"^1(34[0-8]|(3[5-9]|5[017-9]|8[278])\\d)\\d{7}$";
  16. /**
  17. *中国联通:ChinaUnicom
  18. *130,131,132,152,155,156,185,186
  19. */
  20. NSString*CU=@"^1(3[0-2]|5[256]|8[56])\\d{8}$";
  21. /**
  22. *中国电信:ChinaTelecom
  23. *133,1349,153,180,189
  24. */
  25. NSString*CT=@"^1((33|53|8[09])[0-9]|349)\\d{7}$";
  26. /**
  27. *大陆地区固话及小灵通
  28. *区号:010,020,021,022,023,024,025,027,028,029
  29. *号码:七位或八位
  30. */
  31. //NSString*PHS=@"^0(10|2[0-5789]|\\d{3})\\d{7,8}$";
  32. NSPredicate*regextestmobile=[NSPredicatepredicateWithFormat:@"SELFMATCHES%@",MOBILE];
  33. NSPredicate*regextestcm=[NSPredicatepredicateWithFormat:@"SELFMATCHES%@",CM];
  34. NSPredicate*regextestcu=[NSPredicatepredicateWithFormat:@"SELFMATCHES%@",CU];
  35. NSPredicate*regextestct=[NSPredicatepredicateWithFormat:@"SELFMATCHES%@",CT];
  36. if(([regextestmobileevaluateWithObject:mobileNum]==YES)
  37. ||([regextestcmevaluateWithObject:mobileNum]==YES)
  38. ||([regextestctevaluateWithObject:mobileNum]==YES)
  39. ||([regextestcuevaluateWithObject:mobileNum]==YES))
  40. {
  41. if([regextestcmevaluateWithObject:mobileNum]==YES){
  42. NSLog(@"ChinaMobile");
  43. }elseif([regextestctevaluateWithObject:mobileNum]==YES){
  44. NSLog(@"ChinaTelecom");
  45. }elseif([regextestcuevaluateWithObject:mobileNum]==YES){
  46. NSLog(@"ChinaUnicom");
  47. }else{
  48. NSLog(@"Unknow");
  49. }
  50. returnYES;
  51. }
  52. else
  53. {
  54. returnNO;
  55. }
  56. }


(6)邮箱验证、电话号码验证:

[objc] view plain copy 派生到我的代码片
  1. //是否是有效的正则表达式
  2. +(BOOL)isValidateRegularExpression:(NSString*)strDestinationbyExpression:(NSString*)strExpression
  3. {
  4. NSPredicate*predicate=[NSPredicatepredicateWithFormat:@"SELFMATCHES%@",strExpression];
  5. return[predicateevaluateWithObject:strDestination];
  6. }
  7. //验证email
  8. +(BOOL)isValidateEmail:(NSString*)email{
  9. NSString*strRegex=@"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{1,5}";
  10. BOOLrt=[CommonToolsisValidateRegularExpression:emailbyExpression:strRegex];
  11. returnrt;
  12. }
  13. //验证电话号码
  14. +(BOOL)isValidateTelNumber:(NSString*)number{
  15. NSString*strRegex=@"[0-9]{1,20}";
  16. BOOLrt=[CommonToolsisValidateRegularExpression:numberbyExpression:strRegex];
  17. returnrt;
  18. }


(7)NSDate进行筛选

[objc] view plain copy 派生到我的代码片
  1. //日期在十天之内:
  2. NSDate*endDate=[[NSDatedate]retain];
  3. NSTimeIntervaltimeInterval=[endDatetimeIntervalSinceReferenceDate];
  4. timeInterval-=3600*24*10;
  5. NSDate*beginDate=[[NSDatedateWithTimeIntervalSinceReferenceDate:timeInterval]retain];
  6. //对coredata进行筛选(假设有fetchRequest)
  7. NSPredicate*predicate_date=
  8. [NSPredicatepredicateWithFormat:@"date>=%@ANDdate<=%@",beginDate,endDate];
  9. [fetchRequestsetPredicate:predicate_date];
  10. //释放retained的对象
  11. [endDaterelease];
  12. [beginDaterelease];


——————CocoaChina论坛

NSPredicate是一个Foundation类,它指定数据被获取或者过滤的方式。它的查询语言就像SQL的WHERE和正则表达式的交叉一样,提供了具有表现力的,自然语言界面来定义一个集合被搜寻的逻辑条件。

NSPredicate是一个Foundation类,它指定数据被获取或者过滤的方式。它的查询语言就像SQL的WHERE和正则表达式的交叉一样,提供了具有表现力的,自然语言界面来定义一个集合被搜寻的逻辑条件。

相比较抽象的谈论它,展示NSPredicate的使用方法更加容易,所以我们来重新审视 NSSortDescriptor中使用的示例数据集吧:
索引 1234
AliceBobCharlieQuentin
SmithJonesSmithAlberts
年龄24273331

      
  1. @interfacePerson:NSObject
  2. @propertyNSString*firstName;
  3. @propertyNSString*lastName;
  4. @propertyNSNumber*age;
  5. @end
  6. @implementationPerson
  7. -(NSString*)description{
  8. return[NSStringstringWithFormat:@"%@%@",self.firstName,self.lastName];
  9. }
  10. @end
  11. #pragmamark-
  12. NSArray*firstNames=@[@"Alice",@"Bob",@"Charlie",@"Quentin"];
  13. NSArray*lastNames=@[@"Smith",@"Jones",@"Smith",@"Alberts"];
  14. NSArray*ages=@[@24,@27,@33,@31];
  15. NSMutableArray*people=[NSMutableArrayarray];
  16. [firstNamesenumerateObjectsUsingBlock:^(idobj,NSUIntegeridx,BOOL*stop){
  17. Person*person=[[Personalloc]init];
  18. person.firstName=firstNames[idx];
  19. person.lastName=lastNames[idx];
  20. person.age=ages[idx];
  21. [peopleaddObject:person];
  22. }];
  23. NSPredicate*bobPredicate=[NSPredicatepredicateWithFormat:@"firstName='Bob'"];
  24. NSPredicate*smithPredicate=[NSPredicatepredicateWithFormat:@"lastName=%@",@"Smith"];
  25. NSPredicate*thirtiesPredicate=[NSPredicatepredicateWithFormat:@"age>=30"];
  26. //["BobJones"]
  27. NSLog(@"Bobs:%@",[peoplefilteredArrayUsingPredicate:bobPredicate]);
  28. //["AliceSmith","CharlieSmith"]
  29. NSLog(@"Smiths:%@",[peoplefilteredArrayUsingPredicate:smithPredicate]);
  30. //["CharlieSmith","QuentinAlberts"]
  31. NSLog(@"30's:%@",[peoplefilteredArrayUsingPredicate:thirtiesPredicate]);
集合中使用NSPredicate
Foundation提供使用谓词(predicate)来过滤NSArray/NSMutableArray&NSSet/NSMutableSet的方法。
不可变的集合,NSArray&NSSet,有可以通过评估接收到的predicate来返回一个不可变集合的方法filteredArrayUsingPredicate:和filteredSetUsingPredicate:。
可变集合,NSMutableArray&NSMutableSet,可以使用方法filterUsingPredicate:,它可以通过运行接收到的谓词来移除评估结果为FALSE的对象。
NSDictionary可以用谓词来过滤它的键和值(两者都为NSArray对象)。NSOrderedSet可以由过滤的NSArray或NSSet生成一个新的有序的集,或者NSMutableSet可以简单的removeObjectsInArray:,来传递通过否定predicate过滤的对象。
Core Data中使用NSPredicate
NSFetchRequest有一个predicate属性,它可以指定管理对象应该被获取的逻辑条件。谓词的使用规则在这里同样适用,唯一的区别在于,在管理对象环境中,谓词由持久化存储助理(persistent store coordinator)评估,而不像集合那样在内存中被过滤。
谓词语法
替换
%@是对值为字符串,数字或者日期的对象的替换值。
%K是key path的替换值。

      
  1. NSPredicate*ageIs33Predicate=[NSPredicatepredicateWithFormat:@"%K=%@",@"age",@33];
  2. //["CharlieSmith"]
  3. NSLog(@"Age33:%@",[peoplefilteredArrayUsingPredicate:ageIs33Predicate]);
$VARIABLE_NAME是可以被NSPredicate -predicateWithSubstitutionVariables:替换的值。

      
  1. NSPredicate*namesBeginningWithLetterPredicate=[NSPredicatepredicateWithFormat:@"(firstNameBEGINSWITH[cd]$letter)OR(lastNameBEGINSWITH[cd]$letter)"];
  2. //["AliceSmith","QuentinAlberts"]
  3. NSLog(@"'A'Names:%@",[peoplefilteredArrayUsingPredicate:[namesBeginningWithLetterPredicatepredicateWithSubstitutionVariables:@{@"letter":@"A"}]]);
基本比较
=, ==:左边的表达式和右边的表达式相等。
>=, =>:左边的表达式大于或者等于右边的表达式。
<=, =<:左边的表达式小于等于右边的表达式。
>:左边的表达式大于右边的表达式。
<:左边的表达式小于右边的表达式。
!=, <>:左边的表达式不等于右边的表达式。
BETWEEN:左边的表达式等于右边的表达式的值或者介于它们之间。右边是一个有两个指定上限和下限的数值的数列(指定顺序的数列)。比如,1 BETWEEN { 0 , 33 },或者$INPUT BETWEEN { $LOWER, $UPPER }。
基本复合谓词
AND, &&:逻辑与.
OR, ||:逻辑或.
NOT, !:逻辑非.
字符串比较
字符串比较在默认的情况下是区分大小写和音调的。你可以在方括号中用关键字符c和d来修改操作符以相应的指定不区分大小写和变音符号,比如firstname BEGINSWITH[cd] $FIRST_NAME。
BEGINSWITH:左边的表达式以右边的表达式作为开始。
CONTAINS:左边的表达式包含右边的表达式。
ENDSWITH:左边的表达式以右边的表达式作为结束。
LIKE:左边的表达式等于右边的表达式:?和*可作为通配符,其中?匹配1个字符,*匹配0个或者多个字符。
MATCHES:左边的表达式根据ICU v3(更多内容请查看 ICU User Guide for Regular Expressions)的regex风格比较,等于右边的表达式。
合计操作
关系操作
ANY,SOME:指定下列表达式中的任意元素。比如,ANY children.age < 18。
ALL:指定下列表达式中的所有元素。比如,ALL children.age < 18。
NONE:指定下列表达式中没有的元素。比如,NONE children.age < 18。它在逻辑上等于NOT (ANY ...)。
IN:等于SQL的IN操作,左边的表达必须出现在右边指定的集合中。比如,name IN { 'Ben', 'Melissa', 'Nick' }。
数组操作
array[index]:指定数组中特定索引处的元素。
array[FIRST]:指定数组中的第一个元素。
array[LAST]:指定数组中的最后一个元素。
array[SIZE]:指定数组的大小。
布尔值谓词
TRUEPREDICATE:结果始终为真的谓词。
FALSEPREDICATE:结果始终为假的谓词。
NSCompoundPredicate
我们见过与&或被用在谓词格式字符串中以创建复合谓词。然而,我们也可以用NSCompoundPredicate来完成同样的工作。
例如,下列谓词是相等的:

      
  1. [NSCompoundPredicateandPredicateWithSubpredicates:@[[NSPredicatepredicateWithFormat:@"age>25"],[NSPredicatepredicateWithFormat:@"firstName=%@",@"Quentin"]]];
  2. [NSPredicatepredicateWithFormat:@"(age>25)AND(firstName=%@)",@"Quentin"];
虽然语法字符串文字更加容易输入,但是在有的时候,你需要结合现有的谓词。在那些情况下,你可以使用NSCompoundPredicate -andPredicateWithSubpredicates:&-orPredicateWithSubpredicates:。
NSComparisonPredicate
同样的,如果你在读过 上周的文章之后发现你使用了太多的NSExpression的话,NSComparisonPredicate可以帮助你解决这个问题。
就像NSCompoundPredicate一样,NSComparisonPredicate从子部件构建了一个NSPredicate--在这种情况下,左侧和右侧都是NSExpression。 分析它的类的构造函数可以让我们一窥NSPredicate的格式字符串是如何解析的:

      
  1. +(NSPredicate*)predicateWithLeftExpression:(NSExpression*)lhs
  2. rightExpression:(NSExpression*)rhs
  3. modifier:(NSComparisonPredicateModifier)modifier
  4. type:(NSPredicateOperatorType)type
  5. options:(NSUInteger)options

参数
lhs:左边的表达式。
rhs:右边的表达式。
modifier:应用的修改符。(ANY或者ALL)
type:谓词运算符类型。
options:要应用的选项。没有选项的话则为0。
NSComparisonPredicate类型

      
  1. enum{
  2. NSLessThanPredicateOperatorType=0,
  3. NSLessThanOrEqualToPredicateOperatorType,
  4. NSGreaterThanPredicateOperatorType,
  5. NSGreaterThanOrEqualToPredicateOperatorType,
  6. NSEqualToPredicateOperatorType,
  7. NSNotEqualToPredicateOperatorType,
  8. NSMatchesPredicateOperatorType,
  9. NSLikePredicateOperatorType,
  10. NSBeginsWithPredicateOperatorType,
  11. NSEndsWithPredicateOperatorType,
  12. NSInPredicateOperatorType,
  13. NSCustomSelectorPredicateOperatorType,
  14. NSContainsPredicateOperatorType,
  15. NSBetweenPredicateOperatorType
  16. };
  17. typedefNSUIntegerNSPredicateOperatorType;

NSComparisonPredicate选项
NSCaseInsensitivePredicateOption:不区分大小写的谓词。你通过在谓词格式字符串中加入后面带有[c]的字符串操作(比如,"NeXT" like[c] "next")来表达这一选项。
NSDiacriticInsensitivePredicateOption:忽视发音符号的谓词。你通过在谓词格式字符串中加入后面带有[d]的字符串操作(比如,"naïve" like[d] "naive")来表达这一选项。
NSNormalizedPredicateOption:表示待比较的字符串已经被预处理了。这一选项取代了NSCaseInsensitivePredicateOption和NSDiacriticInsensitivePredicateOption,旨在用作性能优化的选项。你可以通过在谓词格式字符串中加入后面带有[n]的字符串(比如,"WXYZlan" matches[n] ".lan")来表达这一选项。
NSLocaleSensitivePredicateOption:表明要使用<,<=,=,=>,> 作为比较的字符串应该使用区域识别的方式处理。你可以通过在<,<=,=,=>,>其中之一的操作符后加入[l](比如,"straße" >[l] "strasse")以便在谓词格式字符串表达这一选项。
Block谓词
最后,如果你实在不愿意学习NSPredicate的格式语法,你也可以学学NSPredicate +predicateWithBlock:。

      
  1. NSPredicate*shortNamePredicate=[NSPredicatepredicateWithBlock:^BOOL(idevaluatedObject,NSDictionary*bindings){
  2. return[[evaluatedObjectfirstName]length]<=5;
  3. }];
  4. //["AliceSmith","BobJones"]
  5. NSLog(@"ShortNames:%@",[peoplefilteredArrayUsingPredicate:shortNamePredicate]);
...好吧,虽然使用predicateWithBlock:是懒人的做法,但它也并不是一无是处。
事实上,因为block可以封装任意的计算,所以有一个查询类是无法以NSPredicate格式字符串形式来表达的(比如对运行时被动态计算的值的评估)。而且当同一件事情可以用NSExpression结合自定义选择器来完成时,block为完成工作提供了一个方便的接口。
重要提示:由predicateWithBlock:生成的NSPredicate不能用于由SQLite存储库支持的Core Data数据的提取要求。
我知道我已经说过很多次了,可是NSPredicate真的是Cocoa的优势之一。其他语言的第三方库如果能有它一半的能力就已经很幸运了--更别提标准库了。对于我们这些应用和框架开发者来说,有它作为标准组件使得我们在处理数据时有了很大的优势。
和NSExpression一样,NSPredicate一直在提醒我们Foundation有多么好:它不仅仅十分有用,它精致的构架和设计也是我们写代码时灵感的来源.


-(BOOL)isValidateEmail:(NSString *)email
{
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    return [emailTest evaluateWithObject:email];
}


-(BOOL) isValidateMobile:(NSString *)mobile
{
    //手机号以13, 15,18开头,八个 \d 数字字符
    NSString *phoneRegex = @"^((13[0-9])|(15[^4,\\D])|(18[0,0-9]))\\d{8}$";
    NSPredicate *phoneTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",phoneRegex];
//    NSLog(@"phoneTest is %@",phoneTest);
    return [phoneTest evaluateWithObject:mobile];
}

 
BOOL validateCarNo(NSString* carNo) 
{ 
    NSString *carRegex = @"^[A-Za-z]{1}[A-Za-z_0-9]{5}$"; 
    NSPredicate *carTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",carRegex]; 
    NSLog(@"carTest is %@",carTest); 
    return [carTest evaluateWithObject:carNo]; 
} 


其实iOS中有三种方式来实现正则表达式的匹配。现在将他们都记录在这里:
1.利用NSPredicate(谓词)匹配
2.利用rangeOfString:option:直接查找

NSString *searchText = @"// Do any additional setup after loading the view, typically from a nib.";

NSRange range = [searchText rangeOfString:@"(?:[^,])*\\." options:NSRegularExpressionSearch];

if (range.location != NSNotFound) {

NSLog(@"%@", [searchText substringWithRange:range]);

}

options中设定NSRegularExpressionSearch就是表示利用正则表达式匹配,会返回第一个匹配结果的位置。


3.使用正则表达式类

NSString *searchText = @"// Do any additional setup after loading the view, typically from a nib.";

NSError *error = NULL;

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?:[^,])*\\." options:NSRegularExpressionCaseInsensitive error:&error];

NSTextCheckingResult *result = [regex firstMatchInString:searchText options:0 range:NSMakeRange(0, [searchText length])];

if (result) {

NSLog(@"%@\n", [searchText substringWithRange:result.range]);

}

使用系统的正则表达式类(NSRegularExpression)会返回匹配的多个结果。

小结:
第一种匹配需要学习NSPredicate的写法,需要查阅苹果相关技术文档;如果只关心第一个匹配的结果,第二种匹配较为简洁;如果需要匹配多个结果,同时匹配多次,第三种方式效率会更高。


参考来源:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值