iOS 正则表达式

正则表达式

界定符

表示一个正则表达式的开始和结束

1
/[0-9]/

在iOS中不加界定符

原子

①可见原子

Unicode 编码表中用键盘输出后可见的字符

1
2
3
4
- 标点;“_?. 等等
- 英文数字a-z,A-Z,0-9
- 数理化公式符号
- 其他可见字符

②不可见原子

Unicode 编码表中用键盘输出后不可见的字符

1
2
3
4
5
- 换行符\n
- 回车 \r
- 制表符 \t
- 空格
- 其他不可见符号

元字符

①原子的筛选方式

1
2
3
- |   匹配两个或者多个分支选择
- [] 匹配方括号中的任意一个原子
- [^] 匹配除方括号中的原子之外的任意字符

②原子的集合

1
2
3
4
5
6
7
- .  匹配除换行符之外的任意字符
- \d 匹配任意一个十进制数字,即[0-9]
- \D 匹配任意一个非十进制数字,即[^0-9]
- \s 匹配一个不可见原子,即[\f\n\r\t\v]
- \S 匹配一个可见原子,即[^\f\n\r\t\v]
- \w 匹配任意一个数字、字母或下划线,即[0-9a-zA-Z_]
- \W 匹配任意一个非数字、字母或下划线,即[^0-9a-zA-Z_]
量词
1
2
3
4
5
6
- {n}   表示其前面的原子恰好出现 n 次
- {n,} 表示其前面的原子至少出现 n 次
- {n,m} 表示其前面的原子恰好出现 n 次,最多出现m次
- * 匹配0次、1次或者多次其之前的原子,即{0,}
- + 匹配一次或者多次其之前的原子,即{1,}
- ? 匹配0次或者1次其之前的原子,即{0,1}

边界控制与模式单元
1
2
3
- ^  匹配字符串开始的位置
- $ 匹配字符串结尾的位置
- () 匹配其中的整体为一个原子

修正模式

常见的修正模式

1
2
3
4
5
- U 懒惰匹配
- i 忽略英文字母大小写
- x 忽略空白
- s 让元字符 ` . ` 匹配包括换行符在内所有字符
- e iOS 暂未知


好以上是正则的简单介绍,详细请看这个:正则表达式30分钟入门教程

iOS 正则表达式

服务器每次返回的时间格式是这个样子的:

1
2016-08-13T13:06:48Z

显示的时候只要年月日 或者是时分秒:

1
2
2016-08-13
13:06:48

这里常用的有两种方法

  1. 使用 NSDateFormatter 格式化,来解析这时间格式的字符串,转换成 NSDate 格式,然后在格式化一次转换成相应的格式(这种方法感觉很蛋疼,折腾了两次);
  2. 使用 NSString 分割方法:
1
- (NSArray<NSString *> *)componentsSeparatedByString:(NSString *)separator;

以 “T” 进行分割,最终得出自己想要的字符串;


这两种方法是常用的方法,但是用起来总感觉不爽,后来想想还可以用 正则表达式,那就试试

使用正则表达式来解析这个时间格式

在iOS中通常使用 “NSRegularExpression” 进行字符串匹配,一般是这个样子:

1
2
3
4
5
6
7
8
     NSString *string = @"字符串xxxx";
NSString *regexString = @"正则表达式";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexString options:NSRegularExpressionCaseInsensitive error:nil];
NSArray *matches = [regex matchesInString:string options:NSMatchingReportProgress range:NSMakeRange(0, string.length)];
for (NSTextCheckingResult *match in matches) {
// do something...
}
}

下面我们来写这个正则来匹配出 年月日 和 时分秒。具体的正则写法请自行Google,不过我在这里介绍一个好网站regexper可以分析你写的正则表达式;匹配时间的正则我已经写好了:

1
^(\\d{4}-\\d{1,2}-\\d{1,2})T(\\d{1,2}:\\d{1,2}:\\d{1,2})Z$

在正则表达式中 有group之分,看上面的正则:

1
2
3
4
group#1:
(\\d{4}-\\d{1,2}-\\d{1,2})
group#2:
(\\d{1,2}:\\d{1,2}:\\d{1,2})

group#1 匹配的是年月日,group#2匹配的是时分秒,正则匹配之后,我们是可以分别取出这两个group匹配出来的值的;在iOS中“NSRegularExpression”类,也是有的;下面是匹配:

1
2
3
4
5
6
7
8
9
10
11
12
NSString *string = @"2016-08-13T13:06:48Z";
NSString *regexString = @"^(\\d{4}-\\d{1,2}-\\d{1,2})T(\\d{1,2}:\\d{1,2}:\\d{1,2})Z$";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexString options:NSRegularExpressionCaseInsensitive error:nil];
NSArray *matches = [regex matchesInString:string options:NSMatchingReportProgress range:NSMakeRange(0, string.length)];
for (NSTextCheckingResult *match in matches) {
NSString* group0 = [string substringWithRange:[match rangeAtIndex:0]];
NSLog(@"group0 :%@", group0);
NSString* group1 = [string substringWithRange:[match rangeAtIndex:1]];
NSLog(@"group1 :%@", group1);
NSString* group2 = [string substringWithRange:[match rangeAtIndex:2]];
NSLog(@"group2 :%@", group2);
}

使用正则匹配出来之后,NSTextCheckingResult 中 使用 “[match rangeAtIndex:xxx]” 可以取出来。在这里NSTextCheckingResult 中 :

1
2
3
4
NSTextCheckingResult 类属性numberOfRanges 为3
[match rangeAtIndex:0] 匹配的是全量即:2016-08-13T13:06:48Z
[match rangeAtIndex:1] 匹配的是:2016-08-13
[match rangeAtIndex:2] 匹配的是:13:06:48

这下处理不就简单了许多。