标签:
正则表达式是一种用来进行文本匹配的工具,其语法优美简洁。在开发中,查找、对比以及匹配字符串是家常便饭的业务,通过正则表达式我们将这些业务描 述成某些需求规则,来让我们的代码更美观、实用。例如我们要验证用户输入的密码长度是否满足6~18位的长度,新手最常见的验证方式是判断输入的密码长度
return (textField.text.length >= 6 && textField.text.leng <= 18);
尽管这种判断方式没有任何问题,而上面的验证换做正则表达式的匹配字符就显得短小精悍
^.{6,18}$
还有,大部分的固定电话都是0区号-八位数字的格式,那么正则表达式的匹配如下
^0\\d{2}\-?\\d{8}$
再比如,对于密码强度的认证。如今的密码应该包括一个或以上的大写字母以及小写字母,对此正则表达式的匹配是
(^.*[A-Z]+.*[a-z]+.*$|^.*[a-z]+.*[A-Z]+.*$)
表达式字符解析
如 果是新手开发者,那么很有可能不理解上面的正则表达式。那么我们先看第一个匹配条件,匹配6-18位的密码长度。根据题目的要求,就能够轻易的判断出 {6,18}表示6-18位。其中,{n}匹配字符重复n次;{n,}匹配重复n次或更多次;{n,m}匹配重复n到m之间次数。
那么读者 对^、.和$三个符号可能不明所以。^和$属于特殊符号,前者表示匹配字符串的开头,后者表示匹配字符串的结尾。由于我们有时需要在一段很长的字符串中匹 配某些小片段字符串时(比如在图文混编中匹配长字符串中留空的表情符号),适当使用这两个符号可以减少匹配次数,提高执行效率。
那么结合这几个字符代表含义,可以得出.符号表示任一字符(除换行符之外)。那么还可以得出{6,18}这个特殊符号表示的是前一个符号代表的位数。结合起来说^.{6,18}$匹配一段6至18位长度的字符串,所以可以用来验证密码长度
当然了,.字符的匹配率太高,更多时候我们需要匹配的是具体到数字或者字母,甚至准确的数字和字母。那么除了.字符以外,还有\d用来表示任意的单个数字,\w表示任意一个字母或数字或者直接使用0-9的任意数字表示具体数字。而特殊符号?表示前一个字符为0或者1个。
所以上面的^0\\d{2}\-?\\d{8}$匹配了以数字0开头,接着两个数字,后面跟着-号跟八个数字,然后结尾的字符串,不管是010-88888888,还是02098989898都能进行正确匹配。
最后的一个表达式可能是最复杂的表达式,根据上面对部分符号的解析。我们可以把
^.*[A-Z]+.*[a-z]+.*$|^.*[a-z]+.*[A-Z]+.*$
拆分成 ^.*[A-Z]+.*[a-z]+.*$ 跟 ^.*[a-z]+.*[A-Z]+.*$
这 两个单独的表达式,而中间的|不难猜到就是逻辑的或。我们将对前一个进行拆分,来一步步识别这个表达式的匹配规则。这里教大家我拆分表达式的方法:我把表 达式的字符分为两类:值表达和修饰表达。所谓值表达就是说这个符号表示了某个值,就像\d表示数字,.表示任意非换行符字符。修饰表达用来修饰值达成某种 条件,比如{2}表示前面一个值重复两次,*表示前一个值重复0次或者更多次。根据这种方法,那么^.*[A-Z]+.*[a-z]+.*$可以拆分成部 分:^$、 .* 、 [A-Z]+ 、 [a-z]+。
^$就不再多说。
.*这里要介绍的就是*表示前一个值符号重复任意次数。
[A-Z]+中-表示从左边的值到右边的值之间所有值形成的闭集合;[]方括号表示的值必须是括号中间集合的子集,要注意的是括号里面可以有多个集合,比如[A-Z0-9a-z]表示匹配任意一个大小写字母或数字;+同*有点像,但是+表示的是至少一个的重复值。
结 合上面的解析,那么^.*[A-Z]+.*[a-z]+.*$表示以任意数量的字符开头,然后跟着一个大写字母,大写字母后面有任意数量的字符以及一个小 写字母,然后又是任意数量的数字、字母或者字符。而^.*[a-z]+.*[A-Z]+.*$表示小写字母在大写字母前面任意数量的字符的位置,两个结合 匹配可以确保字符串中包括至少一个小写字母和一个大写字母。
ps:有一点要注意,上面展示的表达式解析时\d这些特殊符号在我们的代码中多了一个\,这是因为\本身是转义符号,为了保证表达式能正常匹配,我们要给\进行一次转义,所以就变成了\\。基本上所有的符号字符都需要转义。
语法/字符说明表
值表达
. 匹配除换行符外的任意字符
\w 匹配字母或者数字的字符
\W 匹配任意不是字母或数字的字符
\s 匹配任意的空白符(空格、制表符、换行符)
\S 匹配任意不是空白符的字符
\d 匹配任意数字
\D 匹配任意非数字的字符
\b 匹配单词的结尾或者开头的字符
\B 匹配任意不是单词结尾或开头的字符
[^x] 匹配任意非x的字符。如[^[a-z]]匹配非小写字母的任意字符
^ 匹配字符串的开头
$ 匹配字符串的结尾
修饰表达
* 匹配重复任意次数
+ 匹配重复一次以上的次数
? 匹配一次或零次
{n} 匹配重复n次
{n,} 匹配重复n次或n次以上
{n,m} 匹配重复最少n次最多m次
除了上面列出的字符外,还有包括表示位置指定等较难运用的其他正则表达式,但上面的字符已经足够我们正常使用了。想了解更多知识可以度娘Google。
代码实操
上面我们只是简单的讲解了正则表达式中各个字符代表的意义,那么在iOS开发中应该怎么使用。对于有意使用正则规则来匹配的开发者,我的建议是封装成为类别方法,一次封装,多次调用。下面用我自己封装的代码进行说明。这些方法通过扩展UITextField方法来实现:
@interface UITextField (LXDValidate)
/*! 判断文本框是否为空(非正则表达式)*/
- (BOOL)isEmpty;
/*! 判断邮箱是否正确*/
- (BOOL)validateEmail;
/*! 判断验证码是否正确*/
- (BOOL)validateAuthen;
/*! 判断密码格式是否正确*/
- (BOOL)validatePassword;
/*! 判断手机号码是否正确*/
- (BOOL)validatePhoneNumber;
/*! 自己写正则传入进行判断*/
- (BOOL)validateWithRegExp: (NSString *)regExp;
@end
方法实现文件:
#import "UITextField+LXDValidate.h"
@implementation UITextField (LXDValidate)
- (BOOL)isEmpty
{
return self.text.length == 0;
}
- (BOOL)validateEmail
{
return [self validateWithRegExp: @"^[a-zA-Z0-9]{4,}@[a-z0-9A-Z]{2,}\\.[a-zA-Z]{2,}$"];
}
- (BOOL)validateAuthen
{
return [self validateWithRegExp: @"^\\d{5,6}$"];
}
- (BOOL)validatePassword
{
NSString * length = @"^\\w{6,18}$"; //长度
NSString * number = @"^\\w*\\d+\\w*$"; //数字
NSString * lower = @"^\\w*[a-z]+\\w*$"; //小写字母
NSString * upper = @"^\\w*[A-Z]+\\w*$"; //大写字母
return [self validateWithRegExp: length] && [self validateWithRegExp: number] && [self validateWithRegExp: lower] && [self validateWithRegExp: upper];
}
- (BOOL)validatePhoneNumber
{
NSString * reg = @"^1\\d{10}$";
return [self validateWithRegExp: reg];
}
- (BOOL)validateWithRegExp: (NSString *)regExp
{
NSPredicate * predicate = [NSPredicate predicateWithFormat: @"SELF MATCHES %@", regExp];
return [predicate evaluateWithObject: self.text];
}
@end
标签:
原文地址:http://www.cnblogs.com/zhanghouqi/p/5930334.html