正则表达式常用语法:
/**
* 正则表达式简单说明
* 语法:
. 匹配除换行符以外的任意字符
\\w 匹配字母或数字或下划线或汉字
\\s 匹配任意的空白符
\\d 匹配数字
\\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
\\W 匹配任意不是字母,数字,下划线,汉字的字符
\\S 匹配任意不是空白符的字符
\\D 匹配任意非数字的字符
\\B 匹配不是单词开头或结束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou]匹配除了aeiou这几个字母以外的任意字符
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复
\\a 报警字符(打印它的效果是电脑嘀一声)
\\b 通常是单词分界位置,但如果在字符类里使用代表退格
\\t 制表符,Tab
\\r 回车
\\v 竖向制表符
\\f 换页符
\\n 换行符
\\e Escape
\\0nn ASCII代码中八进制代码为nn的字符
\\xnn ASCII代码中十六进制代码为nn的字符
\\unnnn Unicode代码中十六进制代码为nnnn的字符
\\cN ASCII控制字符。比如\\cC代表Ctrl+C
\\A 字符串开头(类似^,但不受处理多行选项的影响)
\\Z 字符串结尾或行尾(不受处理多行选项的影响)
\\z 字符串结尾(类似$,但不受处理多行选项的影响)
\\G 当前搜索的开头
\\p{name} Unicode中命名为name的字符类,例如\\p{IsGreek}
(?>exp) 贪婪子表达式
(?<x>-<y>exp) 平衡组
(?im-nsx:exp) 在子表达式exp中改变处理选项
(?im-nsx) 为表达式后面的部分改变处理选项
(?(exp)yes|no) 把exp当作零宽正向先行断言,如果在这个位置能匹配,使用yes作为此组的表达式;否则使用no
(?(exp)yes) 同上,只是使用空表达式作为no
(?(name)yes|no) 如果命名为name的组捕获到了内容,使用yes作为表达式;否则使用no
(?(name)yes) 同上,只是使用空表达式作为no
捕获
(exp) 匹配exp,并捕获文本到自动命名的组里
(?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name'exp)
(?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号
零宽断言
(?=exp) 匹配exp前面的位置
(?<=exp) 匹配exp后面的位置
(?!exp) 匹配后面跟的不是exp的位置
(?<!exp) 匹配前面不是exp的位置
注释
(?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读
*/
下面是项目中常用正则方法:
1.判断是否为电话号码:
正则:
中国移动: ^1([3-9][0-9]|5[0-35-9]|8[025-9])\\d{8}$
中国联通: ^1([3-8][0-8]|(3[5-9]|5[017-9]|8[278])\\d)\\d{7}$
中国电信: ^1([3-8][0-2]|5[256]|8[56])\\d{8}$
中国地区固话及小灵通(不常用): ^1((33|53|8[09])[0-9]|349)\\d{7}$
判断方法:
+ (BOOL)isMobileNumber:(NSString *)telephoneNum{
NSString * MOBILE =@"^1([3-9][0-9]|5[0-35-9]|8[025-9])\\d{8}$";
NSString * CM =@"^1([3-8][0-8]|(3[5-9]|5[017-9]|8[278])\\d)\\d{7}$";
NSString * CU =@"^1([3-8][0-2]|5[256]|8[56])\\d{8}$";
NSPredicate *regextestmobile = [NSPredicatepredicateWithFormat:@"SELF MATCHES %@", MOBILE];
NSPredicate *regextestcm = [NSPredicatepredicateWithFormat:@"SELF MATCHES %@", CM];
NSPredicate *regextestcu = [NSPredicatepredicateWithFormat:@"SELF MATCHES %@", CU];
if ((([regextestmobileevaluateWithObject:telephoneNum] ==YES) || ([regextestcm evaluateWithObject:telephoneNum] ==YES) || ([regextestcu evaluateWithObject:telephoneNum] ==YES))&&telephoneNum.length == 11) {
returnYES;
} else {
returnNO;
}
}
^(0[0-9]{2,3})?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$|(^(13[0-9]|15[0|3|6|7|8|9]|18[8|9])\\d{8}$)
+ (BOOL)checkNumber:(NSString *)number
{
//验证输入的固话中不带 "-"符号
NSString * strNum =@"^(0[0-9]{2,3})?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$|(^(13[0-9]|15[0|3|6|7|8|9]|18[8|9])\\d{8}$)";
NSPredicate *checktest = [NSPredicatepredicateWithFormat:@"SELF MATCHES %@", strNum];
return [checktestevaluateWithObject:number];
}
^([0-9ABCDEFGHJKLMNPQRTUWXY]{2})([0-9]{6})([0-9ABCDEFGHJKLMNPQRTUWXY]{9})([0-9Y])$
+ (BOOL)isSocialCredit18Number:(NSString *)socialCreditNum
{
if(socialCreditNum.length != 18){
returnNO;
}
NSString *scN =@"^([0-9ABCDEFGHJKLMNPQRTUWXY]{2})([0-9]{6})([0-9ABCDEFGHJKLMNPQRTUWXY]{9})([0-9Y])$";
NSPredicate *regextestSCNum = [NSPredicatepredicateWithFormat:@"SELF MATCHES %@", scN];
if (![regextestSCNumevaluateWithObject:socialCreditNum]) {
returnNO;
}
NSArray *ws = @[@1,@3,@9,@27,@19,@26,@16,@17,@20,@29,@25,@13,@8,@24,@10,@30,@28];
NSDictionary *zmDic = @{@"A":@10,@"B":@11,@"C":@12,@"D":@13,@"E":@14,@"F":@15,@"G":@16,@"H":@17,@"J":@18,@"K":@19,@"L":@20,@"M":@21,@"N":@22,@"P":@23,@"Q":@24,@"R":@25,@"T":@26,@"U":@27,@"W":@28,@"X":@29,@"Y":@30};
NSMutableArray *codeArr = [NSMutableArrayarray];
NSMutableArray *codeArr2 = [NSMutableArrayarray];
codeArr[0] = [socialCreditNum substringWithRange:NSMakeRange(0,socialCreditNum.length-1)];
codeArr[1] = [socialCreditNum substringWithRange:NSMakeRange(socialCreditNum.length-1,1)];
int sum = 0;
for (int i = 0; i < [codeArr[0]length]; i++) {
[codeArr2 addObject:[codeArr[0]substringWithRange:NSMakeRange(i, 1)]];
}
NSScanner* scan;
int val;
for (int j = 0; j < codeArr2.count; j++) {
scan = [NSScannerscannerWithString:codeArr2[j]];
if (![scanscanInt:&val] && ![scan isAtEnd]) {
codeArr2[j] = zmDic[codeArr2[j]];
}
}
for (int x = 0; x < codeArr2.count; x++) {
sum += [ws[x] intValue]*[codeArr2[x]intValue];
}
int c18 = 31 - (sum % 31);
for (NSString *keyin zmDic.allKeys) {
if (zmDic[key]==[NSNumbernumberWithInt:c18]) {
if (![codeArr[1]isEqualToString:key]) {
returnNO;
}
}
}
returnYES;
}
- (BOOL)isValidTaxNo {
NSString *taxNoRegex = @"[0-9]\\\\d{13}([0-9]|X)$";
return [self isValidateByRegex:taxNoRegex];
}
- (BOOL)isValidPostalcode {
NSString *postalRegex = @"^[0-8]\\\\d{5}(?!\\\\d)$";
return [self isValidateByRegex:postalRegex];
}
- (BOOL)isEmailAddress {
NSString *emailRegex = @"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\\.[A-Za-z]{2,4}";
return [self isValidateByRegex:emailRegex];
}
/**银行卡号有效性问题Luhn算法
* 现行 16位银联卡现行卡号开头 6位是 622126~622925之间的,7到 15位是银行自定义的,
* 可能是发卡分行,发卡网点,发卡序号,第 16位是校验码。
* 16位卡号校验位采用 Luhm校验方法计算:
* 1,将未带校验位的 15位卡号从右依次编号 1到 15,位于奇数位号上的数字乘以 2
* 2,将奇位乘积的个十位全部相加,再加上所有偶数位上的数字
* 3,将加法和加上校验位能被 10整除。
*/
+ (BOOL)isBankCardNumber:(NSString *)cardNum {
NSString * lastNum = [[cardNumsubstringFromIndex:(cardNum.length-1)]copy];//取出最后一位
NSString * forwardNum = [[cardNumsubstringToIndex:(cardNum.length -1)]copy];//前15或18位
NSMutableArray * forwardArr = [[NSMutableArrayalloc] initWithCapacity:0];
for (int i=0; i<forwardNum.length; i++) {
NSString * subStr = [forwardNumsubstringWithRange:NSMakeRange(i, 1)];
[forwardArr addObject:subStr];
}
NSMutableArray * forwardDescArr = [[NSMutableArrayalloc] initWithCapacity:0];
for (int i = (int)(forwardArr.count-1); i> -1; i--) {//前15位或者前18位倒序存进数组
[forwardDescArr addObject:forwardArr[i]];
}
NSMutableArray * arrOddNum = [[NSMutableArrayalloc] initWithCapacity:0];//奇数位*2的积 < 9
NSMutableArray * arrOddNum2 = [[NSMutableArrayalloc] initWithCapacity:0];//奇数位*2的积 > 9
NSMutableArray * arrEvenNum = [[NSMutableArrayalloc] initWithCapacity:0];//偶数位数组
for (int i=0; i< forwardDescArr.count; i++) {
NSInteger num = [forwardDescArr[i]intValue];
if (i%2) {//偶数位
[arrEvenNum addObject:[NSNumbernumberWithInteger:num]];
}else{//奇数位
if (num * 2 < 9) {
[arrOddNum addObject:[NSNumbernumberWithInteger:num * 2]];
}else{
NSInteger decadeNum = (num * 2) / 10;
NSInteger unitNum = (num * 2) % 10;
[arrOddNum2 addObject:[NSNumbernumberWithInteger:unitNum]];
[arrOddNum2 addObject:[NSNumbernumberWithInteger:decadeNum]];
}
}
}
__block NSInteger sumOddNumTotal = 0;
[arrOddNum enumerateObjectsUsingBlock:^(NSNumber * obj,NSUInteger idx, BOOL *stop) {
sumOddNumTotal += [obj integerValue];
}];
__blockNSInteger sumOddNum2Total = 0;
[arrOddNum2 enumerateObjectsUsingBlock:^(NSNumber * obj,NSUInteger idx, BOOL *stop) {
sumOddNum2Total += [obj integerValue];
}];
__blockNSInteger sumEvenNumTotal =0 ;
[arrEvenNum enumerateObjectsUsingBlock:^(NSNumber * obj,NSUInteger idx, BOOL *stop) {
sumEvenNumTotal += [obj integerValue];
}];
NSInteger lastNumber = [lastNumintegerValue];
NSInteger luhmTotal = lastNumber + sumEvenNumTotal + sumOddNum2Total + sumOddNumTotal;
return (luhmTotal%10 ==0)?YES:NO;
}
/**
* 正则表达式:
1.6~18位同时包含数字和大小写字母 (?![0-9A-Z]+$)(?![0-9a-z]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,18}$
2.6~18位同时包含数字和字母 ^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,18}$
3.不能包含特殊字符 ^[A-Za-z0-9\\u4e00-\u9fa5]+$
*/
+ (NSString *)isOrNoPasswordStyle:(NSString *)passWordName
{
NSString * message;
if (passWordName.length<6) {
message = @"密码不能少于6位,请您重新输入";
}
else if (passWordName.length>18)
{
message = @"密码最大长度为18位,请您重新输入";
}
else if ([selfJudgeTheillegalCharacter:passWordName])
{
message = @"密码不能包含特殊字符,请您重新输入";
}
else if (![selfjudgePassWordLegal:passWordName])
{
message = @"密码必须同时包含字母和数字";
}
return message;
}
+ (BOOL)JudgeTheillegalCharacter:(NSString *)content{
//提示标签不能输入特殊字符
NSString *str =@"^[A-Za-z0-9\\u4e00-\u9fa5]+$";
NSPredicate* emailTest = [NSPredicatepredicateWithFormat:@"SELF MATCHES %@", str];
if (![emailTestevaluateWithObject:content]) {
returnYES;
}
returnNO;
}
+ (BOOL)judgePassWordLegal:(NSString *)pass{
BOOL result ;
// 判断长度大于6位后再接着判断是否同时包含数字和大小写字母
NSString * regex =@"^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,18}$";
NSPredicate *pred = [NSPredicatepredicateWithFormat:@"SELF MATCHES %@", regex];
result = [pred evaluateWithObject:pass];
NSLog(@"%hhd",result);
return result;
}