NSPredicate(正则表达式核心类)

来源:互联网 发布:excel数据保护 编辑:程序博客网 时间:2024/05/17 02:13

一、定义谓词:

Cocoa框架中的NSPredicate用于查询,原理和用法都类似于SQL中的where,作用相当于数据库的过滤取。NSpredicate是一个Foundation类,它指定数据被获取或者过滤的方式。它的查询语言就像SQL的WHERE和正则表达式的交叉一样,提供了具有表现力的,自然语言界面来定义一个集合被搜索的逻辑条件。

NSPredicate对象来代表谓词,它有三个类:NSComparisonPredicate、NSCompoundPredicate和NSExpression,虽然程序实际创建通常是NSPredicate的子类的实例,但实际编程时会直接使用NSPredicate的predicateWithFormat:方法,以一个谓词字符串为参数来创建NSPredicate对象。比如,如下例子:

group.name lick “work”ALL children.age > 12ANY children.age > 12

创建谓词之后,如果谓词中没有占位符参数,即可使用NSPredicate的evaluateWithObject:方法计算谓词的结果,该结果总是一个BOOL值;如果该谓词中有占位符参数,则需要经过如下两步计算谓词的结果:

  • (1)、调用谓词的predicateWithSubstitutionVariables:方法为占位符参数设置参数值;
  • (2)、执行谓词的evaluateWithObject:方法计算谓词的返回结果;
//创建谓词,要求name的以s开头NSPredicate* pred = [NSPredicate predicateWithFormat:@"name like 'l*'"];MyCourse* testCourse = [[MyCourse alloc]initWithNumber:12];MyName* testName = [[MyName alloc]initWithName:@"laowang" andAge:25 andCourse:testCourse];//对testName对象使用谓词判断BOOL result = [pred evaluateWithObject:testName];NSLog(@"testName的name属性是否以s开头:%d",result);//1

二、使用谓词过滤集合

 谓词本身就代表了一个逻辑条件,计算谓词的结果就是返回BOOL类型的值。谓词的一个常用功能就是对集合进行过滤,当程序使用谓词对结合元素进行过滤时,程序将会自动遍历结合元素,并根据集合元素来计算谓词的值,只有当根据某个集合元素计算并返回YES时,该集合元素才会保存下来。
  • (1)、NSArray提供了如下方法使用谓词来过滤集合:

    - (NSArray *)filteredArrayUsingPredicate:(NSPredicate *)predicate;使用指定的谓词过滤NSArray集合,返回该集合中符合谓词条件的元素组成新集合。
  • (2)、NSMutableArray提供了如下方法使用谓词来过滤集合:

    - (void)filterUsingPredicate:(NSPredicate *)predicate;使用指定的谓词过滤NSMutableArray集合,剔除该集合中不符合条件的元素;

    例如:

NSMutableArray* array = [NSMutableArray arrayWithObjects:[NSNumber numberWithInt:50],[NSNumber numberWithInt:42],[NSNumber numberWithInt:20],[NSNumber numberWithInt:64],[NSNumber numberWithInt:56],nil];//创建谓词,要求该对象自身的值大于50NSPredicate* pred1 = [NSPredicate predicateWithFormat:@"SELF > 50"];//使用谓词执行过滤,过滤后只剩下值大于50的集合元素[array filterUsingPredicate:pred1];NSLog(@"值大于50的元素:%@",array);
  • (3)、NSSet提供了如下方法使用谓词来过滤集合:

    - (NSSet *)filteredSetUsingPredicate:(NSPredicate *)predicate;使用指定的谓词过滤NSSet集合,返回该集合中符合谓词条件的元素组成新集合;

    例如:

NSSet* set = [NSSet setWithObjects:[[MyName alloc]initWithName:@"金角大王" andAge:12 andCourse:[[MyCourse alloc]initWithNumber:3]],[[MyName alloc]initWithName:@"银角大王" andAge:13 andCourse:[[MyCourse alloc]initWithNumber:4]],[[MyName alloc]initWithName:@"孙悟空" andAge:14 andCourse:[[MyCourse alloc]initWithNumber:5]], nil];//创建谓词,要求该对象的name值中包含'大王'NSPredicate* pred2 = [NSPredicate predicateWithFormat:@"name CONTAINS '大王'"];//执行过滤,过滤后集合只剩下两个元素NSSet* newSet = [set filteredSetUsingPredicate:pred2];NSLog(@"%@",newSet);
  • (4)、NSMutableSet提供了如下方法使用谓词来过滤集合:

    - (NSOrderedSet *)filteredOrderedSetUsingPredicate:(NSPredicate *)p;使用指定的谓词过滤NSMutableSet集合,剔除该集合中不符合条件的元素;

三、在谓词中使用占位符参数

如果需要在谓词表达式中使用变量,则可以考虑在谓词表达式中使用占位符参数,谓词表达式中支持以下两个占位符参数:

  • (1)、%K:该占位符用于动态传入属性名;
  • (2)、%@:该占位符用于动态设置属性值;

如果在此表达式中使用了展位符参数,则需要在调用predicateWithFormat:方法时为各占位符传入参数;

除此之外,还可以在谓词表达式中使用动态改变的属性值,类似于环境变量,如下:

[NSPredicate predicateWithFormat:@"name CONTAINS $SUBSTR"];
 上面表达式中,$SUBSTR是一个可以动态改变的值,随着程序改变了$SUBSTR的值,该谓词表达式的比较条件就可以动态改变。

如果在谓词表达式使用了形如$SUBSTR的占位符参数,接下来两个方法为这些占位符参数传入参数值:

  • (1)、先调用NSPredicate的predicateWithSubstitutionVariables:方法为占位符参数设置参数值,该方法返回一个可用的NSPredicate对象;
  • (2)、直接调用NSPredicate的evaluateWithObject:substitutionVariables:方法同时完成参数设置和计算结果;
    例如:
NSSet* set = [NSSet setWithObjects:[[MyName alloc]initWithName:@"金角大王" andAge:12 andCourse:[[MyCourse alloc]initWithNumber:3]],[[MyName alloc]initWithName:@"银角大王" andAge:13 andCourse:[[MyCourse alloc]initWithNumber:4]],[[MyName alloc]initWithName:@"孙悟空" andAge:14 andCourse:[[MyCourse alloc]initWithNumber:5]],[[MyName alloc]initWithName:@"猪八戒" andAge:15 andCourse:[[MyCourse alloc]initWithNumber:6]],[[MyName alloc]initWithName:@"天上老君" andAge:16 andCourse:[[MyCourse alloc]initWithNumber:7]],nil];NSString* propPath = @"name";NSString* value = @"大王";//创建谓词,该谓词中包含了两个占位符//后面的两个变量用于为占位符设置参数值NSPredicate* pred = [NSPredicate predicateWithFormat:@"%K CONTAINS %@",propPath,value];//执行过滤,过滤后集合只剩下两个元素,NSSet* newSet = [set filteredSetUsingPredicate:pred];NSLog(@"%@",newSet);//创建谓词,该谓词表达式中使用%K占位符,该占位符使用pass代替//要求被比较对象的age包含$SUBSTR子串NSPredicate* predTemplate = [NSPredicate predicateWithFormat:@"%K CONTAINS $SUBSTR",@"name"];//使用NSDictionary是定SUBSTR的值为‘43’NSPredicate* pred1 = [predTemplate predicateWithSubstitutionVariables:[NSDictionary dictionaryWithObjectsAndKeys:@"大王",@"SUBSTR", nil]];//指定过滤,过滤后的集合只剩下两个NSSet* newSet2 = [set filteredSetUsingPredicate:pred1];NSLog(@"%@",newSet2);

四、谓词表达式语法

1、基本的比较运算符

基本的比较运算符如下:

  • ①、=、==:判断两个表达式是否相等;
  • ②、>=、=>:判断左边表达式的值是否大于或等于右边的表达式的值;
  • ③、<=、=<:判断左边表达式的值是否小于或等于右边的表达式的值;
  • ④、>:判断左边的表达式的值是否大于右边表达式的值;
  • ⑤、<:判断左边的表达式的值是否小于右边表达式的值;
  • ⑥、!=、<>:判断两个表达式是否不相等;
  • ⑦、BETWEEN:BETWEEN表达式必须满足“表达式BETWEEN{下限,上限}”的格式,要求该表达式的值必须大于或等于下限,并小于或等于上限。

2、基本的逻辑运算符

  • ①、AND、&&:逻辑与,要求两个表达式的值都为YES时,结果才是YES;
  • ②、OR、||:逻辑或,要求任何一个表达式为YES时,结果才是YES;
  • ③、NOT、!:逻辑非,用于对原有的表达式结果取反。

3、字符串比较运算符

  • ①、BEGINSWITH:检查某个字符串是否以指定的子串开头;
  • ②、ENDSWITH:检查某个字符串是否以指定的子串结尾;
  • ③、CONTAINS:检查某个字符串是否包含指定的子串;
  • ④、LIKE:检查某个字符串是否匹配指定的字符串模板。LIKE运算符后面可使用字符串模板,该字符串模板允许使用和?两个通配符,其中代表任意多个字符;?代表一个字符。比如“name LIKE er”,这要求name的值包含er子串,则返回YES;比如”name LIKE ??er*“这要求name的值必须先有两个任意字符,接下来是er字符,然后是任意子串,则返回YES;
  • ⑤、MATCHES:检查某个字符串是否匹配指定的正则表达式。MATCHES后面可使用正则表达式,虽然正则表达式的功能是最强大的,但执行效率也是最低的。因此,能用前面运算符解决的谓词表达式,就没有必要使用MATCHES运算符。

注意:需要说明的是这些字符串比较运算符都是区分大小写和重音符号的。字符串比较运算符默认区分大小写和重音符号。如果希望字符串比较运算符不区分大小写和重音符号,可在这些运算符后使用[c]、[d]选项,其中[c]指定不区分大小写,[d]指定不区分重音符号。比如:“name BEGINSWITH[cd] ‘fkja’”。

4、操作集合的运算符

  • ①、ANY、SOME:指定只要集合中任意一个元素满足条件,即可返回YES。例如:ANY children.age < 18,只要children集合中任意一个元素的age小于18,该表达式即可返回YES;
  • ②、ALL:指定要求集合中所有的元素满足条件才能返回YES。例如:ALL children.age < 18,children集合的所有元素的age必须都小于18,该表达式才可返回YES;
  • ③、NONE:指定要求集合中没有任何元素满足条件才返回YES。例如,NONE children.age < 18,children集合中所有元素的age必须都不小于18,该表达式才可返回YES。NONE运算符等价于NOT(ANY …);
  • ④、IN:该运算符基本等价于SQL语句中的IN运算符,只有当左边表达式或值出现右边的集合中才会返回YES。例如:name IN {‘Ben’,’Melissa’,’Nick’},只有当anme的值为’Ben’、’Melissa’,’Nick’之一才返回YES;
  • ⑤、array[index]:返回array数组中index索引处的元素;
  • ⑥、array[FIRST]:返回array数组中第一个元素;
  • ⑦、array[LAET]:返回array数组中最后一个元素;
  • ⑧、array[SIZE]:返回array数组中元素的个数。

5、直接量

 在谓词表达式中使用双引号和单引号的效果是相同的,比如,“abc”和’abc'是完全相同的。但需要指出的是,单引号只能用单引号结束,双引号只能用双引号结束,不能混用。

在谓词表达式中可使用如下直接量:

  • ①、FALSE、NO:代表逻辑假;
  • ②、TRUE、YES:代表逻辑真;
  • ③、NULL、NIL:代表一个空值;
  • ④、SELF:代表正在被判断的对象本身;
  • ⑤、“text”或’text’:代表字符串;
  • ⑥、数组:数组元素以英文逗号隔开。例如:{‘comma’,’separated’,’literal’,’array’};
  • ⑦、数值直接量:包括整数、小数和科学计数法表示形式。比如,1、27、9.2e-5;
  • ⑧、十六进制数:十六进制数以0x开头;
  • ⑨、八进制数、二进制数:八进制数以0o开头;二进制数以0b开头。

五、实例

1、基本信息

属性:name(名字NSString)、age(年龄NSUInteger)、course(课程:number(课程个数));

//人物一MyCourse* course1 = [[MyCourse alloc]initWithNumber:3];MyName* name1 = [[MyName alloc]initWithName:@"chenxiao" andAge:11 andCourse:course1];//人物二MyCourse* course2 = [[MyCourse alloc]initWithNumber:4];MyName* name2 = [[MyName alloc]initWithName:@"laowang" andAge:12 andCourse:course2];//人物数组NSArray *names = [NSArray arrayWithObjects:name1,name2, nil];//谓词NSPredicate *predicate;//含有变量的谓词NSPredicate *predicateTemplate;//判断BOOL result;//返回的结果数组NSArray *results;//含有变量的谓词字典NSDictionary *varDict;

2、判断是否相等

predicate = [NSPredicate predicateWithFormat: @"name == 'chenxiao'"];result = [predicate evaluateWithObject: name1];NSLog (@"%s", (result) ? "YES" : "NO");//YES

3、判断name是否以’C’开头

//是否C开头predicate = [NSPredicate predicateWithFormat: @"name like 'C*'"];result = [predicate evaluateWithObject: name1];NSLog (@"%s", (result) ? "YES" : "NO");//NO

4、筛选names满足条件的元素

//筛选name属性course.number大于3的元素predicate = [NSPredicate predicateWithFormat: @"course.number > 3"];for (MyName *name in names) {     if ([predicate evaluateWithObject: name]) {          NSLog (@"%@", name.name);//laowang     }}

5、返回满足条件的数组

//返回满足条件的数组predicate = [NSPredicate predicateWithFormat: @"course.number < 4"];results = [names filteredArrayUsingPredicate: predicate];for (MyName* name in results) {     NSLog(@"%@",name.name);//chenxiao}

6、还有变量的谓词

//含有变量的谓词predicateTemplate = [NSPredicate predicateWithFormat:@"name == $NAME"];varDict = [NSDictionary dictionaryWithObjectsAndKeys:  @"chenxiao", @"NAME", nil];predicate = [predicateTemplate predicateWithSubstitutionVariables: varDict];NSLog(@"SNORGLE: %@", predicate);//SNORGLE: name == "chenxiao"result = [predicate evaluateWithObject: name1];NSLog (@"%s", (result) ? "YES" : "NO"); //YES

7、谓词字符中添加C语言中常用的运算符

//谓词字符窜还支持c语言中一些常用的运算符predicate = [NSPredicate predicateWithFormat:@"(course.number > 3) AND (course.number < 5)"];results = [names filteredArrayUsingPredicate: predicate];for (MyName* name in results) {     NSLog(@"%@",name.name);//laowang}

8、强大的数组运算符

//强大的数组运算符

  • ①、
predicate = [NSPredicate predicateWithFormat @"course.number BETWEEN {3, 4}"]; //包含3、4results = [names filteredArrayUsingPredicate: predicate];for (MyName* name in results) {    NSLog(@"%@",name.name);//chenxiao/laowang}
  • ②、
NSArray *betweens = [NSArray arrayWithObjects:[NSNumber numberWithInt: 3], [NSNumber numberWithInt: 4], nil];predicate = [NSPredicate predicateWithFormat: @"course.number BETWEEN %@", betweens];results = [names filteredArrayUsingPredicate: predicate];for (MyName* name in results) {    NSLog(@"%@",name.name);//chenxiao/laowang}
  • ③、
NSArray *betweens = [NSArray arrayWithObjects:[NSNumber numberWithInt: 3], [NSNumber numberWithInt: 4], nil];predicateTemplate = [NSPredicate predicateWithFormat: @"course.number BETWEEN $POWERS"];varDict = [NSDictionary dictionaryWithObjectsAndKeys: betweens, @"POWERS", nil];predicate = [predicateTemplate predicateWithSubstitutionVariables: varDict];results = [names filteredArrayUsingPredicate: predicate];for (MyName* name in results) {    NSLog(@"%@",name.name);//chenxiao/laowang}

9、、IN运算符

//IN运算符predicate = [NSPredicate predicateWithFormat: @"name IN { 'chenxiao', 'laowang', 'Badger', 'Flap' }"];results = [names filteredArrayUsingPredicate: predicate];NSLog (@"%@", [results valueForKey: @"name"]);//chengxiao/laowangpredicate = [NSPredicate predicateWithFormat: @"SELF.name IN { 'chenxiao', 'laowang', 'Badger', 'Flap' }"];results = [names filteredArrayUsingPredicate: predicate];NSLog (@"%@", [results valueForKey: @"name"]);//chengxiao/laowang
  • 10、区分大小写、发音字符
//附加符号,[c],[d],[cd],c表示不区分大小写,d表示不区分发音字符,cd表示什么都不区分predicate = [NSPredicate predicateWithFormat: @"name BEGINSWITH 'Chenxiao'"];result = [predicate evaluateWithObject: name1];NSLog (@"%s", (result) ? "YES" : "NO");//NOpredicate = [NSPredicate predicateWithFormat: @"name BEGINSWITH[c] 'Chenxiao'"];result = [predicate evaluateWithObject: name1];NSLog (@"%s", (result) ? "YES" : "NO");//YES

11、正则表达式

// 编写正则表达式:只能是数字或英文,或两者都存在NSString *regex = @"^[a-z0-9A-Z]*$";// 创建谓词对象并设定条件的表达式NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];// 判断的字符串NSString *str = @"Hello哈哈";// 对字符串进行判断BOOL result = [predicate evaluateWithObject:str];NSLog (@"%s", (result) ? "YES" : "NO");//NO
0 0
原创粉丝点击