当前位置: 移动技术网 > IT编程>移动开发>IOS > iOS之正则表达式的使用和谓词(NSPredicate)的使用

iOS之正则表达式的使用和谓词(NSPredicate)的使用

2018年04月05日  | 移动技术网IT编程  | 我要评论

余额宝年收益率,勇者之路2双人无敌版,菊花的诗句

iOS之正则表达式的使用和谓词(NSPredicate)的使用,正则表达式匹配返回的是一个范围,用这个范围去原来的字符串截取,就得到我们想要的字符串;

1.=========字符串匹配

NSString *phoneNo = @"13143503442";

NSRange range = [phoneNo rangeOfString:@"^1[3]\\d{9}$options:NSRegularExpressionSearch];//返回在phoneNo中字符串的位置

if (range.location != NSNotFound) {

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

}

rangeOfString:options:会返回一个NSRange,用来接收匹配的范围,当匹配不到结果时,将会返回一个NSIntegerMax最大值,也就是NSNotFound,因此我们可以用它来判断用户输入的内容是否符合规则。

 

2.============//NSRegularExpression类创建正则表达式-----匹配第一个结果字符串

NSString *url = @"123456789@qq.com";

NSError *error;

// 创建NSRegularExpression对象并指定正则表达式

NSRegularExpression *regex = [NSRegularExpression

regularExpressionWithPattern:@"[^@]*\\."

options:0

error:&error];

if (!error) { // 如果没有错误

// 获取特特定字符串的范围 match.range----抓取了第一个结果

NSTextCheckingResult *match = [regex firstMatchInString:url

options:0

range:NSMakeRange(0, [url length])];

if (match) {

// 截获特定的字符串

NSString *result = [url substringWithRange:match.range];

NSLog(@"%@",result);

}

} else { // 如果有错误,则把错误打印出来

NSLog(@"error - %@", error);

}

// 这个例子是从字符串里检索出以“@”开头“.”结尾的区间字符串,最后检索出来的字符串结尾包括“.”,因此此例子最终输出结果为“qq.”

3.==============//NSRegularExpression类之抓取多个结果

// 当一个字符串有多个符合特定规则的字符,我们可以分别获取到符合特定规则的字符:

NSString *regex = @"\\-\\d*\\.";

NSString *str = @"-34023242.-34203020.";

NSError *error;

NSRegularExpression *regular = [NSRegularExpression regularExpressionWithPattern:regex

options:NSRegularExpressionCaseInsensitive

error:&error];

// 对str字符串进行匹配----把匹配到的字符串全部放入数组,数组中的对象是NSTextCheckingResult

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);

}

4.============正则表达式中符号的解释

表1.常用的元字符
代码 说明
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意的空白符
\d 匹配数字
\b 匹配单词的开始或结束,\b开始并且\b结束的就时一个单词;
^ 匹配字符串的开始
$ 匹配字符串的结束
 


表2.常用的限定符
代码/语法 说明
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次,就是?前面的字符可以存在一次,也可以不存在
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
 

表2 中的符号是针对仅临它的前一个字符



**************[ ]--------------方括号匹配单个字符;匹配方括号中的一个字符*****************


[aeiou]就匹配任何一个英文元音字母,

[.?!]匹配标点符号(.或?或!)。

我们也可以指定一个字符范围,像[0-9]代表的含意与\d就是完全一致的:一位数字;

同理[a-z0-9A-Z_]也完全等同于\w(如果只考虑英文的话);

***********字符转义 \**************

\\---------- \

\*---------- *

\(---------- (

\.---------- .

************或 | ************** |两边的先各自匹配,最后在匹配 |;

x|y:匹配x或y。例如,“z|food”能匹配“z”或“food”。“(z|f)ood”则匹配“zood”或“food”。

***************括号( )**************

(\d{1,3}\.){3}\d{1,3}是一个简单的IP地址匹配表达式;(\d{1,3}\.){3}匹配一到三位数字加上一个英文句号(这个整体也就是这个分组)重复3次,最后再加上一个一到三位的数字(\d{1,3})。

**************************反义****************

 
\W匹配任意不是字母,数字,下划线,汉字的字符
 
\S匹配任意不是空白符的字符
 
\D匹配任意非数字的字符
 
\B匹配不是单词开头或结束的位置
 
[^x]匹配除了x以外的任意字符

[^aeiou]匹配除了aeiou这几个字母以外的任意字符

 

******************分组向后引用************************

使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。

后向引用用于重复搜索前面某个分组匹配的文本。例如,\1代表分组1匹配的文本。难以理解?请看示例:

\b(\w+)\b\s+\1\b可以用来匹配重复的单词,像go go, 或者kitty kitty。这个表达式首先是一个单词,也就是单词开始处和结束处之间的多于一个的字母或数字(\b(\w+)\b),这个单词会被捕获到编号为1的分组中,然后是1个或几个空白符(\s+),最后是分组1中捕获的内容(也就是前面匹配的那个单词)(\1)。

你也可以自己指定子表达式的组名。要指定一个子表达式的组名,请使用这样的语法:(?\w+)(或者把尖括号换成'也行:(?'Word'\w+)),这样就把\w+的组名指定为Word了。要反向引用这个分组捕获的内容,你可以使用\k,所以上一个例子也可以写成这样:\b(?\w+)\b\s+\k\b。

使用小括号的时候,还有很多特定用途的语法。下面列出了最常用的一些:

表4.常用分组语法
分类 代码/语法 说明
捕获 (exp) 匹配exp,并捕获文本到自动命名的组里
(?exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name'exp)
(?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号
零宽断言 (?=exp) 匹配exp前面的位置
(?<=exp) 匹配exp后面的位置
(?!exp) 匹配后面跟的不是exp的位置
(? 匹配前面不是exp的位置
注释 (?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人
 

 

 

 

==============谓词(NSPredicate)==================

 

只要我们使用谓词(NSPredicate)都需要为谓词定义谓词表达式,而这个表达式必须是一个返回BOOL的值。

谓词表达式由表达式、运算符和值构成。

1.===============evaluateWithObject:是否有匹配的,返回BOOL

NSString*regex =@"^[0-9]*$";//正则匹配小数

NSPredicate*pred = [NSPredicatepredicateWithFormat:@"SELF MATCHES %@", regex];

BOOLisMatch = [predevaluateWithObject:@"99999"];//是否有匹配pre的,有返回YES,没有匹配返回NO;

NSLog(@"--result---%d",isMatch);

 

2.==========

1.***********比较运算符

=、==:判断两个表达式是否相等,在谓词中=和==是相同的意思都是判断,而没有赋值这一说

NSNumber *testNumber = @123;

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF = 123"];

if ([predicate evaluateWithObject:testNumber]) {//YES

NSLog(@"testString:%@", testNumber);

}

>=,=>:判断左边表达式的值是否大于或等于右边表达式的值

<=,=<:判断右边表达式的值是否小于或等于右边表达式的值

>:判断左边表达式的值是否大于右边表达式的值

<:判断左边表达式的值是否小于右边表达式的值

!=、<>:判断两个表达式是否不相等

BETWEEN:BETWEEN表达式必须满足表达式 BETWEEN {下限,上限}的格式,要求该表达式必须大于或等于下限,并小于或等于上限

NSNumber *testNumber = @123;

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF BETWEEN {100, 200}"];

if ([predicate evaluateWithObject:testNumber]) {

NSLog(@"testString:%@", testNumber);

} else {

NSLog(@"不符合条件");

}

2.*************逻辑运算符

AND、&&:逻辑与,要求两个表达式的值都为YES时,结果才为YES。

NSArray *testArray = @[@1, @2, @3, @4, @5, @6];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF > 2 && SELF < 5"];

NSArray *filterArray = [testArray filteredArrayUsingPredicate:predicate];//过滤数组后得到新的数组

NSLog(@"filterArray:%@", filterArray);//结果为:filterArray:(3,4)

 

OR、||:逻辑或,要求其中一个表达式为YES时,结果就是YES

NOT、 !:逻辑非,对原有的表达式取反

3.******************字符串比较运算符

BEGINSWITH:检查某个字符串是否以指定的字符串开头(如判断字符串是否以a开头:BEGINSWITH 'a')

ENDSWITH:检查某个字符串是否以指定的字符串结尾

CONTAINS:检查某个字符串是否包含指定的字符串

LIKE:检查某个字符串是否匹配指定的字符串模板。其之后可以跟?代表一个字符通配和*代表任意多个字符通配符。比如"name LIKE '*ac*'",这表示name的值中包含ac则返回YES;"name LIKE '?ac*'",表示name的第2、3个字符为ac时返回YES。

MATCHES:检查某个字符串是否匹配指定的正则表达式。虽然正则表达式的执行效率是最低的,但其功能是最强大的,也是我们最常用的。例如:上面的例子1;

注:字符串比较都是区分大小写和重音符号的。如:café和cafe是不一样的,Cafe和cafe也是不一样的。如果希望字符串比较运算不区分大小写和重音符号,请在这些运算符后使用[c],[d]选项。其中[c]是不区分大小写,[d]是不区分重音符号,其写在字符串比较运算符之后,比如:name LIKE[cd] 'cafe',那么不论name是cafe、Cafe还是café上面的表达式都会返回YES。

4.*******************集合运算符

ANY、SOME:集合中任意一个元素满足条件,就返回YES。

ALL:集合中所有元素都满足条件,才返回YES。

NONE:集合中没有任何元素满足条件就返回YES。如:NONE person.age < 18,表示person集合中所有元素的age>=18时,才返回YES。

IN:等价于SQL语句中的IN运算符,只有当左边表达式或值出现在右边的集合中才会返回YES。我们通过一个例子来看一下

NSArray *filterArray = @[@"ab", @"abc"];

NSArray *array = @[@"a", @"ab", @"abc", @"abcd"];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)", filterArray];

NSLog(@"%@", [array filteredArrayUsingPredicate:predicate]);

代码的作用是将array中和filterArray中相同的元素去除,输出为:(a,abcd)

array[index]:返回array数组中index索引处的元素

array[FIRST]:返回array数组中第一个元素

array[LAST]:返回array数组中最后一个元素

array[SIZE]:返回array数组中元素的个数

5.*****************直接量

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

FALSE、NO:代表逻辑假

TRUE、YES:代表逻辑真

NULL、NIL:代表空值

SELF:代表正在被判断的对象自身

"string"或'string':代表字符串

数组:和c中的写法相同,如:{'one', 'two', 'three'}。

数值:包括证书、小数和科学计数法表示的形式

十六进制数:0x开头的数字

八进制:0o开头的数字

二进制:0b开头的数字

6.********************保留字

下列单词都是保留字(不论大小写)

AND、OR、IN、NOT、ALL、ANY、SOME、NONE、LIKE、CASEINSENSITIVE、CI、MATCHES、CONTAINS、BEGINSWITH、ENDSWITH、BETWEEN、NULL、NIL、SELF、TRUE、YES、FALSE、NO、FIRST、LAST、SIZE、ANYKEY、SUBQUERY、CAST、TRUEPREDICATE、FALSEPREDICATE

注:虽然大小写都可以,但是更推荐使用大写来表示这些保留字

 

7.============数组的过滤方法:

NSArray提供了如下方法使用谓词来过滤集合

- (NSArray*)filteredArrayUsingPredicate:(NSPredicate *)predicate:使用指定的谓词过滤NSArray集合,返回符合条件的元素组成的新集合-------新数组

NSMutableArray提供了如下方法使用谓词来过滤集合

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

NSSet提供了如下方法使用谓词来过滤集合

- (NSSet*)filteredSetUsingPredicate:(NSPredicate *)predicate NS_AVAILABLE(10_5, 3_0):作用同NSArray中的方法

NSMutableSet提供了如下方法使用谓词来过滤集合

- (void)filterUsingPredicate:(NSPredicate *)predicate NS_AVAILABLE(10_5, 3_0):作用同NSMutableArray中的方法。

通过上面的描述可以看出,使用谓词过滤不可变集合和可变集合的区别是:过滤不可变集合时,会返回符合条件的集合元素组成的新集合;过滤可变集合时,没有返回值,会直接剔除不符合条件的集合元素

8.=========================在谓词中使用占位符参数

@implementation ZLPersonModel

- (instancetype)initWithName:(NSString *)name age:(NSUInteger)age sex:(ZLPersonSex)sex
{
    if (self = [super init]) {
        _name = name;
        _age = age;
        _sex = sex;
    }
    return self;
}

+ (instancetype)personWithName:(NSString *)name age:(NSUInteger)age sex:(ZLPersonSex)sex
{
    return [[self alloc] initWithName:name age:age sex:sex];
}

- (NSString *)description
{
    return [NSString stringWithFormat:@"[name = %@, age = %ld, sex = %ld]", self.name, self.age, self.sex];
}
@end

 

 

首先如果我们想在谓词表达式中使用变量,那么我们需要了解下列两种占位符:

%K:用于动态传入属性名

%@:用于动态设置属性值

其实相当于变量名与变量值

除此之外,还可以在谓词表达式中使用动态改变的属性值,就像环境变量一样

NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF CONTAINS $VALUE"];

上述表达式中,$VALUE是一个可以动态变化的值,它其实最后是在字典中的一个key,所以可以根据你的需要写不同的值,但是必须有$开头,随着程序改变$VALUE这个谓词表达式的比较条件就可以动态改变。

下面我们通过一个例子来看看这三个重要的占位符应该如何使用:

NSArray *array = @[[ZLPersonModel personWithName:@"Jack" age:20 sex:ZLPersonSexMale],

[ZLPersonModel personWithName:@"Rose" age:22 sex:ZLPersonSexFamale],

[ZLPersonModel personWithName:@"Jackson" age:30 sex:ZLPersonSexMale],

[ZLPersonModel personWithName:@"Johnson" age:35 sex:ZLPersonSexMale]];

// 定义一个property来存放属性名,定义一个value来存放值

NSString *property = @"name";

NSString *value = @"Jack";

// 该谓词的作用是如果元素中property属性含有值value时就取出放入新的数组内,这里是name包含Jack

NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K CONTAINS %@", property, value];

NSArray *newArray = [array filteredArrayUsingPredicate:pred];

NSLog(@"newArray:%@", newArray);

输出为

newArray:(

"[name = Jack, age = 20, sex = 0]",

"[name = Jackson, age = 30, sex = 0]"

)

// 创建谓词,属性名改为age,要求这个age包含$VALUE字符串

NSPredicate *predTemp = [NSPredicate predicateWithFormat:@"%K > $VALUE", @"age"];

// 指定$SUBSTR的值为 25 这里注释中的$SUBSTR改为$VALUE

NSPredicate *pred1 = [predTemp predicateWithSubstitutionVariables:@{@"VALUE" : @25}];

NSArray *newArray1 = [array filteredArrayUsingPredicate:pred1];

NSLog(@"newArray1:%@", newArray1);

输出为newArray1:(

"[name = Jackson, age = 30, sex = 0]",

"[name = Johnson, age = 35, sex = 0]"

)

 

// 修改 $SUBSTR的值为32, 这里注释中的SUBSTR改为$VALUE

NSPredicate *pred2 = [predTemp predicateWithSubstitutionVariables:@{@"VALUE" : @32}];

NSArray *newArray2 = [array filteredArrayUsingPredicate:pred2];

NSLog(@"newArray2:%@", newArray2);

输出为newArray2:(

"[name = Johnson, age = 35, sex = 0]"

)


如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

  • ios uicollectionview实现横向滚动

    现在使用卡片效果的app很多,之前公司让实现一种卡片效果,就写了一篇关于实现卡片的文章。文章最后附有demo实现上我选择了使用uicollectionview ... [阅读全文]
  • iOS UICollectionView实现横向滑动

    本文实例为大家分享了ios uicollectionview实现横向滑动的具体代码,供大家参考,具体内容如下uicollectionview的横向滚动,目前我使... [阅读全文]
  • iOS13适配深色模式(Dark Mode)的实现

    iOS13适配深色模式(Dark Mode)的实现

    好像大概也许是一年前, mac os系统发布了深色模式外观, 看着挺刺激, 时至今日用着也还挺爽的终于, 随着iphone11等新手机的发售, ios 13系统... [阅读全文]
  • ios 使用xcode11 新建项目工程的步骤详解

    ios 使用xcode11 新建项目工程的步骤详解

    xcode11新建项目工程,新增了scenedelegate这个类,转而将原appdelegate负责的对ui生命周期的处理担子接了过来。故此可以理解为:ios... [阅读全文]
  • iOS实现转盘效果

    本文实例为大家分享了ios实现转盘效果的具体代码,供大家参考,具体内容如下demo下载地址: ios转盘效果功能:实现了常用的ios转盘效果,轮盘抽奖效果的实现... [阅读全文]
  • iOS开发实现转盘功能

    本文实例为大家分享了ios实现转盘功能的具体代码,供大家参考,具体内容如下今天给同学们讲解一下一个转盘选号的功能,直接上代码直接看viewcontroller#... [阅读全文]
  • iOS实现轮盘动态效果

    本文实例为大家分享了ios实现轮盘动态效果的具体代码,供大家参考,具体内容如下一个常用的绘图,主要用来打分之类的动画,效果如下。主要是ios的绘图和动画,本来想... [阅读全文]
  • iOS实现九宫格连线手势解锁

    本文实例为大家分享了ios实现九宫格连线手势解锁的具体代码,供大家参考,具体内容如下demo下载地址:效果图:核心代码://// clockview.m// 手... [阅读全文]
  • iOS实现卡片堆叠效果

    本文实例为大家分享了ios实现卡片堆叠效果的具体代码,供大家参考,具体内容如下如图,这就是最终效果。去年安卓5.0发布的时候,当我看到安卓全新的material... [阅读全文]
  • iOS利用余弦函数实现卡片浏览工具

    iOS利用余弦函数实现卡片浏览工具

    本文实例为大家分享了ios利用余弦函数实现卡片浏览工具的具体代码,供大家参考,具体内容如下一、实现效果通过拖拽屏幕实现卡片移动,左右两侧的卡片随着拖动变小,中间... [阅读全文]
验证码:
移动技术网