iOS之NSPredicate(正则表达式和UIBarController)
本文转发至:https://segmentfault.com/a/1190000000623005
NSPredicate,这个类和我上一篇博文中提到的valueForKeyPath一样很强大。它的使用主要集中在两个方法中
NSArray
- (NSArray *)filteredArrayUsingPredicate:(NSPredicate *)predicate;
NSMutableArray
- (void)filterUsingPredicate:(NSPredicate *)predicate;
还有NSSet和NSMutableSet也可以用这个类筛选。
下面我就来一一介绍这个类的用法,相信大家看完后会和我一样认为这个类真的很强大。
筛选用法
- 利用成员实例方法
筛选出长度大于3的字符串
NSArray *array = @[@"jim", @"cook", @"jobs", @"sdevm"];
NSPredicate *pre = [NSPredicate predicateWithFormat:@"length > 3"];
NSLog(@"%@", [array filteredArrayUsingPredicate:pre]);
打印
(
cook,
jobs,
sdevm
)
lenght就是对数组成员执行[xxxx lenght]然后判断返回的NSUInteger值是否大于3。扩展到NSString其他方法比如integerValue
NSArray *array = @[@"2", @"3", @"4", @"5"];
NSPredicate *pre = [NSPredicate predicateWithFormat:@"integerValue >= %@", @3];
NSLog(@"%@", [array filteredArrayUsingPredicate:pre]);
如果我不想用任何实例方法,想筛选成员本身应该怎么做呢。这时候就可以用self来代替
NSPredicate *pre = [NSPredicate predicateWithFormat:@"self CONTAINS %@", @3];
CONTAINS用法后面会讲到
再扩展到模型
Test.h
@interface Test : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSNumber *code;
@end
Test *test1 = [[Test alloc]init];
test1.name = @"西湖";
test1.code = @1;
Test *test2 = [[Test alloc]init];
test2.name = @"西溪湿地";
test2.code = @2;
Test *test3 = [[Test alloc]init];
test3.name = @"灵隐寺";
test3.code = @3;
NSArray *array = @[test1, test2, test3];
NSPredicate *pre = [NSPredicate predicateWithFormat:@"code >= %@", @2];
NSLog(@"%@", [array filteredArrayUsingPredicate:pre]);
筛选出数组成员[test code]方法(code属性的get方法)返回值>=2的成员。这里的比较运算符同样也可以使用==、!=、<=、<。
其实==不仅可以用来比较NSNumber对象,还可以用来判断NSString对象是否相同。
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name == %@", @"西湖"];
筛选出name是"西湖"的对象数组。
- ###NSString对象的操作
前面提到==比较运算符可以起到- (BOOL)isEqualToString:(NSString *)aString;方法的效果,来判断字符串是否相同。那么字符串中包含某个字符串应该如何判断呢,在NSPredicate中可以用CONTAINS(大小写都可以)来表示包含关系。
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name CONTAINS %@", @"湖"];
当判断的时候需要忽略大小写可以使用[cd]
[c] 忽略大小写
[d] 忽略重音符号
[cd]既不区分大小写,也不区分发音符号。
使用:
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@", @"abc"];
再涉及到一些更复杂的查询语句,比如判断字符串以某个字符串开头或者结尾,通配符的使用。
BEGINSWITH(已某个字符串开头, begins with)
NSString *targetString = @"h";
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name BEGINSWITH %@",targetString];
ENDSWITH(已某个字符串结尾, ends with)
NSString *targetString = @"ing";
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name ENDSWITH %@",targetString];
通配符 LIKE
*代表一个或者多个或者是空
?代表一个字符
Test *test1 = [[Test alloc]init];
test1.name = @"absr";
test1.code = @1;
Test *test2 = [[Test alloc]init];
test2.name = @"asb";
test2.code = @2;
Test *test3 = [[Test alloc]init];
test3.name = @"raskj";
test3.code = @3;
NSArray *array = @[test1, test2, test3];
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name LIKE %@", @"?b*"];
NSLog(@"%@", [array filteredArrayUsingPredicate:pre]);
结果是只有test1符合,like也可以接受[cd]
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name LIKE[cd] %@", @"?b*"];
关系运算,包括了IN、BETWEEN、AND、OR、NOT
IN(之中)
NSPredicate *pre = [NSPredicate predicateWithFormat:@"code IN %@", @[@1, @3]];
判断code是否@1或者是@2,也就是是否在数组中。
OR(或,可以用||代替)
OR可以用来代替IN达到同样的效果,但是OR更灵活。
NSPredicate *pre = [NSPredicate predicateWithFormat:@"code == %@ OR code == %@ ", @1, @3];
效果和IN一样,但是OR可以判断不只一个属性
NSPredicate *pred = [NSPredicate predicateWithFormat:@"code == %@ OR name == %@ ", @1, @"asb"];
BETWEEN(之间)
通常用于判断NSNumber对象
NSPredicate *pred = [NSPredicate predicateWithFormat:@"code BETWEEN {1, 3}"];
判断code是否>=1且<=3
AND(且,可以用&&代替)
NSPredicate *pred = [NSPredicate predicateWithFormat:@"code >= %@ AND code <=%@", @1, @3];
NOT(非,可以用!代替)
NOT最常见的用法就是从一个数组中剔除另外一个数组的数据,可能有点绕,举个例子就很明朗了。
NSArray *arrayFilter = @[@"abc1", @"abc2"];
NSArray *arrayContent = @[@"a1", @"abc1", @"abc4", @"abc2"];
NSPredicate *thePredicate = [NSPredicate predicateWithFormat:@"NOT (SELF in %@)", arrayFilter];
NSLog(@"%@",[arrayContent filteredArrayUsingPredicate:thePredicate]);
打印
(
a1,
abc4
)
比起循环比较再加到新数组中,简单的不止一两点。
前面提到的都是用+ (NSPredicate *)predicateWithFormat:(NSString *)predicateFormat, ...;方法创建,还有另一种常用的方法:+ (NSPredicate*)predicateWithBlock:(BOOL (^)(id evaluatedObject, NSDictionary *bindings))block,用Block形式创建
NSPredicate *pre = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
Test *test = (Test *)evaluatedObject;
if (test.code.integerValue > 2) {
return YES;
}
else{
return NO;
}
}];
参数evaluatedObject表示数组成员,block必须返回YES或者NO,分别表示匹配还是不匹配。请忽略bindings参数,具体作用我也没搞清楚。
多重筛选
如果需要匹配数个属性的筛选,用AND或者OR来串联显然有点麻烦,NSCompoundPredicate类可以满足我们的需求,它可以将多个NSPredicate对象的组合,组合方式可以是AND或者OR。
NSPredicate *pre1 = [NSPredicate predicateWithFormat:@"code >= %@", @3];
NSPredicate *pre2 = [NSPredicate predicateWithFormat:@"code <= %@", @2];
//以AND形式组合
NSPredicate *pre = [NSCompoundPredicate andPredicateWithSubpredicates:@[pre1,pre2]];
//以OR形式组合
NSPredicate *pre = [NSCompoundPredicate orPredicateWithSubpredicates:@[pre1, pre2]];
匹配用法
其实NSPredicate不仅可以用于筛选,还可以用来判断匹配直接返回是否符合,主要方法是- (BOOL)evaluateWithObject:(id)object;,用法:
Test *test1 = [[Test alloc]init];
test1.name = @"absr";
test1.code = @1;
NSPredicate *pres = [NSPredicate predicateWithFormat:@"code == %@", @2];
BOOL match = [pres evaluateWithObject:test1];
当然最常用的还是配合配合正则表达式,列举几个常用的正则
是否以a开头以e结尾
NSString *string=@"assdbfe";
NSString *targetString=@"^a.+e$";
NSPredicate *pres = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", targetString];
BOOL match = [pres evaluateWithObject:string];
是否是邮箱
NSString *strRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{1,5}";
是否是手机号
NSString *strRegex = @"[0-9]{1,20}";
坑
不得不说,在利用+ (NSPredicate *)predicateWithFormat:(NSString *)predicateFormat, ...;方法创建的NSPredicate对象的时候有个坑。
在某些情况下,类似于上面例子中的code字符串不是很明确,创建的时候就会这样使用
Test *test1 = [[Test alloc]init];
test1.name = @"absr";
test1.code = @1;
Test *test2 = [[Test alloc]init];
test2.name = @"asb";
test2.code = @2;
Test *test3 = [[Test alloc]init];
test3.name = @"raskj";
test3.code = @3;
NSArray *array = @[test1, test2, test3];
NSPredicate *pre = [NSPredicate predicateWithFormat:@"%@ == %@", @"code", @2];
NSLog(@"%@", [array filteredArrayUsingPredicate:pre]);
注意NSPredicate对象的初始化方式。运行这块代码你会发现test2对象没有被查询出来。打印pre发现"code" == 2,这说明查找的是"code"方法的返回值,这显然行不通。
如果查询的是属性,比如code是Test类的属性,那么利用下面的创建方式
NSPredicate *pre = [NSPredicate predicateWithFormat:@"%K == %@", @"code", @2];
就不会被坑
注意:%K的K必须是大写。
最后
NSPredicate几乎可以满足所有形式的查询,配合Core Data的数据库查询当然不在话下。NSPredicate用法不只这些,有兴趣的同学可以看下nshipster网站的这篇博文,里面提到了一些我没有涉及到的用法。
iOS之NSPredicate(正则表达式和UIBarController)的更多相关文章
- iOS中运用正则表达式
iOS中运用正则表达式来匹配短信验证码,电话号码,邮箱等是比较常见的. 在iOS中运用正则表达式主要有三种方式: -:通过谓词下面是实例代码: - (BOOL)regularExpresionWith ...
- iOS开发-正则表达式3种形式
转至:http://www.cnblogs.com/GarveyCalvin/p/4250145.html iOS开发-正则表达式的使用方法 前 言:在表单验证中,我们经常会使用到正则,因为我们需要用 ...
- iOS:转载:IOS谓词--NSPredicate
IOS谓词--NSPredicate 分类: IOS应用2013-02-19 17:24 6792人阅读 评论(1) 收藏 举报 Cocoa 提供了NSPredicate 用于指定过滤条件,谓词是指在 ...
- iOS开发-通过正则表达式判断字符串是否为纯阿拉伯数字
iOS开发-通过正则表达式判断字符串是否为纯阿拉伯数字 简述:NSString * regex_0 = @"\\d{1,}"; /*允许首位为0*/ NSString * re ...
- iOS 手机 邮箱 正则表达式
//iOS代码//判断邮箱格式是否正确的代码: //利用正则表达式验证 -(BOOL)isValidateEmail:(NSString *)email { NSString *emailRegex ...
- iOS开发-NSPredicate
Cocoa中谓词(Predicate)提供了一个通用的查询方式处理数据,可以获取和指定数据的过滤形式,Cocoa实际开发中可以是使用NSPredicate及其父类NSComparisonPredica ...
- iOS三种正则表达式
1.利用NSPredicate(谓词)匹配 例如匹配有效邮箱: NSString *email = @"nijino_saki@.com": NSString *regex = @ ...
- iOS开发-正则表达式的使用方法
前言:在表单验证中,我们经常会使用到正则,因为我们需要用它来判断用户输入的字符是否为合法的,如果是不合法的,那么应该提示用户输入错误,并不让提交至服务器.我们也可以通过正则表达式,从用户输入的字符串中 ...
- iOS开发之正则表达式
正则表达式用于字符串处理.表单验证等场合,实用高效.现将一些常用的表达式收集于此,以备不时之需. 匹配中文字符的正则表达式: [\u4e00-\u9fa5]评注:匹配中文还真是个头疼的事,有了这个表达 ...
随机推荐
- docker镜像与容器概念
本文用图文并茂的方式介绍了容器.镜像的区别和Docker每个命令后面的技术细节,能够很好的帮助读者深入理解Docker. 这篇文章希望能够帮助读者深入理解Docker的命令,还有容器(containe ...
- oracle中触发器的讲解
触发器在数据库里以独立的对象存储,它与存储过程和函数不同的是,存储过程与函数需要用户显示调用才执行,而触发器是由一个事件来启动运行.即触发器是当某个事件发生时自动地隐式运行.并且,触发器不能接收参数. ...
- 用GeneratedKeyHolder获得新建数据主键值
public User createUser(final User user) { final String sql = "insert into sys_users(username, p ...
- Hibernate 系列教程16-二级缓存
pom.xml <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate- ...
- UIImagePikerController 浅析
原文链接:http://www.jianshu.com/p/2ac85aca4468 UIImagePickerController是iOS系统提供的和系统的相册和相机交互的一个类,可以用来获取相册的 ...
- HDU2579--Dating with girls(2)--(DFS, 判重)
Dating with girls(2) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- android 多个shortCut快捷方式实现以及对58同城快捷方式的实现思路的研究
这几天,项目中有个新需求,需要按照模块添加不同的快捷方式到桌面上,从而方便用户的使用.特意进行了研究并分析了下58上面桌面快捷方式的实现. 首先多个shortcut的实现: <activity ...
- Ubuntu 14.04 待机死机问题原来是自己改了这个配置
使用专有驱动没问题.使用开源驱动就会死机.驱动还是厂商的好@@
- java工程开发之图形化界面之(第五课)
下面我们将: 一)更加完整的解释Graphics类 二)使用方法来更清晰的重新编写前面图形小应用程序之一 三)介绍一些其他的绘图的方法 四)介绍方法init,它是类似于paint但是用于不同用途的另一 ...
- linux tomcat服务器优化配置
在 /usr/local/tomcat/bin/catalina.sh里首行加入, 防止内存不够的问题 JAVA_OPTS="-Xms512m -Xmx1024m -Xss1024K -XX ...