来个图片放松一下啊我们经常会遇到验证一个用户的操作数据是否合法,我们最好的方式是用正则去检测用户的行为操作是否正确
正则匹配整数和浮点数
需求:检测文本中的数字,并改变颜色,数字都是序列化的样式文本:当前已经使用的存储
空间大小为3.2GB,下载文件占用788MB,还剩余6.7GB空间,总容量为12GB.
我们需要匹配出来一下几个数字
3.2GB
788MB
6.7GB
12GB
我们如果第一眼看上去你觉得要如何去做呢,我们今天要的不仅是匹配,还要获取到对应的数值
这个匹配我们使用系统的NSRegularExpression
,进行内容的匹配,开始我想到了三种规则:如下
-
\\d*\\.\\d*[M|G]B
这种规则只适合含有小数点的数值,等到项目中用的时候才发现整数没有匹配上去,继续修改下面 -
(((\\d*\\.\\d*)MB)|((\\d*\\.\\d*)GB))
这个是一位PHP大牛写的,我仔细分解了一下,似乎我写的那个就可以了,但是还是匹配到整数就错误。 -
(\\d*(\\.\\d*)?)[M|G]B
这个才是我们想要的,既能匹配小数,又可以匹配整数,这个是我考虑之后稍作修改,检测结果是正常的
第三种情况的匹配代码实例如下:
NSString *searchText = @"当前手机已使用存储大小为3.2GB,已下载文件占用899MB,剩余空间大小5.8GB,当前总容量为12GB";
NSError *error = NULL;
//@"\\d*\\.\\d*[M|G]B" 匹配字符串中连续规则的数字序列
//@"(((\\d*\\.\\d*)MB)|((\\d*\\.\\d*)GB))" 匹配规则全部序列
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(\\d*(\\.\\d*)?)[M|G]B"
options:NSRegularExpressionCaseInsensitive error:&error];
NSTextCheckingResult *result = [regex firstMatchInString:searchText options:0 range:NSMakeRange(0, [searchText length])];
NSArray * matches1 = [regex matchesInString:searchText options:NSMatchingReportProgress range:NSMakeRange(0, [searchText length])];
for (NSTextCheckingResult * test in matches1) {
NSString *tagValuestr = [searchText substringWithRange:test.range];
NSLog(@"tagvalue = %@",tagValuestr);
}
if (result) {
NSLog(@"%@", [searchText substringWithRange:result.range]);
}
控制台输出结果为:
2016-03-15 17:41:19.608 RegularExp[54814:2551313] tagvalue = 3.2GB
2016-03-15 17:41:19.608 RegularExp[54814:2551313] tagvalue = 899MB
2016-03-15 17:41:19.608 RegularExp[54814:2551313] tagvalue = 5.8GB
2016-03-15 17:41:19.608 RegularExp[54814:2551313] tagvalue = 12GB
2016-03-15 17:41:19.609 RegularExp[54814:2551313] 3.2GB
我们可以发现,这个就是我们想要的结果
result
是单个结果,使用matches
是获取多个结果
我们再说一下获取URL参数的正则
代码如下:
NSError *error1;
NSString *regTags=[[NSString alloc] initWithFormat:@"(^|&|\\?)+%@=+([^&]*)(&|$)",@"adc"];
NSRegularExpression *regex1 = [NSRegularExpression regularExpressionWithPattern:regTags
options:NSRegularExpressionCaseInsensitive
error:&error1];
// 执行匹配的过程
NSString *webaddress=@"http://www.baidu.com/dd/adb.htm?adc=e12&xx=lkw&dalsjd=12";
NSArray *matches = [regex1 matchesInString:webaddress
options:0
range:NSMakeRange(0, [webaddress length])];
for (NSTextCheckingResult *match in matches) {
//NSRange matchRange = [match range];
//NSString *tagString = [webaddress substringWithRange:matchRange]; // 整个匹配串
// NSRange r1 = [match rangeAtIndex:1];
// if (!NSEqualRanges(r1, NSMakeRange(NSNotFound, 0))) { // 由时分组1可能没有找到相应的匹配,用这种办法来判断
// //NSString *tagName = [webaddress substringWithRange:r1]; // 分组1所对应的串
// return @"";
// }
NSString *tagValue = [webaddress substringWithRange:[match rangeAtIndex:2]]; // 分组2所对应的串
// NSLog(@"分组2所对应的串:%@\n",tagValue);
NSLog(@"tagvalue = %@",tagValue);
}
控制台的输出
2016-03-15 17:41:19.609 RegularExp[54814:2551313] tagvalue = e12
以上是对NSRegularExpression 这个类的使用
下面我们扩展一些实用的东西:
方法一、 使用谓词NSPredicate
创建正则表达式
一般我们只使用谓词仅供开发者判断用户输入的字符串是否合法,并没有其他要求
// 编写正则表达式:只能是数字或英文,或两者都存在
NSString *regex = @"^[a-z0-9A-Z]*$";
// 创建谓词对象并设定条件的表达式
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
// 判断的字符串
NSString *str = @"Hello100";
// 对字符串进行判断
if ([predicate evaluateWithObject:str]) {
NSLog(@"Match");
}
上面判断之后的结果就是会输出 Match ,如果我们替换一下字符串为-、= ! 之类的,那么判断就不会进入。
方法二、 通过NSRegularExpression 获取指定的对象
我们可以过滤掉一些东西获取到我们想要的结果,代码更清晰:
NSString *url = @"8888@163.com";
NSError *error;
// 创建NSRegularExpression对象并指定正则表达式
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:@"[^@]*\\."
options:0
error:&error];
if (!error) { // 如果没有错误
// 获取特特定字符串的范围
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);
}
上面这个列子我们是从特定字符串中检索以“@”开头 “.” 结尾的区间字符串,所以最终获取到的字符串结尾包括点“.”,最终输出的是“163.”;
方法三、NSRegularExpression 获取多个结果,也就是最上面我们的需求
我们讲解一个获取连续数字序列的正则
NSString *regex = @"\\-\\d*\\.";
NSString *str = @"-111.-666.-888.";
NSError *error;
NSRegularExpression *regular = [NSRegularExpression regularExpressionWithPattern:regex
options:NSRegularExpressionCaseInsensitive
error:&error];
// 对str字符串进行匹配
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);
}
@"\\-\\d*\\.";
我们这里的规则是-号开头,\ 代表特殊字符转义,不参与匹配,“\d” 相当于 [0-9] ,有\ 开始的规则,需要加入转义字符“、”
方法三的输出结果是
-111.
-666.
-888.
通过打印结果,我们可以得知,我们通过方法三的结果是多个,获取到我们想要的结果。
注:我们把常用的字符注释一下
-
“\” :将下一个字符标记为一个特殊字符、或一个原义字符、或者一个向后引用,或者一个八进制转义符。例如:“\\n”匹配“\n” "\n"。序列“\\” 匹配“\” 而 “\(” 匹配“(”
。 "^": 匹配输入字符串的开始位置,如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。
"$" : 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。
"*": 匹配前面的子表达式零次或多次(大于等于0次)。例如,zo*能匹配“z”,“zo”以及“zoo”。*等价于{0,}。
"+":匹配前面的子表达式一次或多次(大于等于1次)。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。
"?": 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”中的“do”。?等价于{0,1}。
"{n}":n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。
"{n,}":n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。
"{n,m}":m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。
"?":当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。
".":匹配除“\r\n”之外的任何单个字符。要匹配包括“\r\n”在内的任何字符,请使用像“[\s\S]”的模式。
"\s" :"匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。"
正则先说到这里,请查看链接:正则使用说明
网友评论