正则表达式在iOS开发中的应用

孙据
• 阅读 3518

在iOS开发过程中,正则的使用还是比较常见,用来判断用户名、手机号等的输入。当碰到这种需求的时候,部分开发的第一印象可能是使用 NSPredicateSELF MATCHES %@ 进行判断,但遗憾的是此方法并非万能,存在检查不出来的情况。其实苹果专门提供了 NSRegularExpression 这个类来做正则校验。

NSPredicate

NSPredicate 可能是我们一开始接触iOS正则实现的方法,但现实是它只能简单的完成正则功能,并没有 NSRegularExpression 强大,同时还存在校验不出来的情况。

NSString *regEx = @"<正则表达式>";
NSString *string = @"<待匹配的字符串>";

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regEx];
BOOL matched = [predicate evaluateWithObject:string];
NSLog(@"是否匹配 = %d", matched);

NSRegularExpression,真正的正则实现

初始化NSRegularExpression

/// 初始化NSRegularExpression,如果出错则会返回nil,并带有error
/// @param pattern 正则表达式
/// @param options 模式选项,一般设成 kNilOptions
/// @parma error 错误
+ (nullable NSRegularExpression *)regularExpressionWithPattern:(NSString *)pattern options:(NSRegularExpressionOptions)options error:(NSError **)error;

关于NSRegularExpressionOptions

typedef NS_OPTIONS(NSUInteger, NSRegularExpressionOptions) {
   NSRegularExpressionCaseInsensitive             = 1 << 0, //不区分字母大小写的模式
   NSRegularExpressionAllowCommentsAndWhitespace  = 1 << 1, //忽略掉正则表达式中的空格和#号之后的字符
   NSRegularExpressionIgnoreMetacharacters        = 1 << 2, //将正则表达式整体作为字符串处理
   NSRegularExpressionDotMatchesLineSeparators    = 1 << 3, //允许.匹配任何字符,包括换行符  
   NSRegularExpressionAnchorsMatchLines           = 1 << 4, //允许^和$符号匹配行的开头和结尾
   NSRegularExpressionUseUnixLineSeparators       = 1 << 5, //设置\n为唯一的行分隔符,否则所有的都有效。
   NSRegularExpressionUseUnicodeWordBoundaries    = 1 << 6 //使用Unicode TR#29标准作为词的边界,否则所有传统正则表达式的词边界都有效
};

前面提到 options 一般设成 kNilOptions,它的效果就是区分大小写,严格校验。

匹配

获取匹配的个数

NSString *regEx = @"<正则表达式>";
NSString *string = @"<待匹配的字符串>";
NSError *error;
NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:regEx options:kNilOptions error:&error];
if (error) {
    NSLog(@"error = %@", error);
}

NSUInteger number = [regularExpression numberOfMatchesInString:string options:kNilOptions range:NSMakeRange(0, string.length)];
NSLog(@"匹配的个数 = %lu", (unsigned long)number);

BOOL matched = (number != 0);
NSLog(@"是否匹配 = %d", matched);

获取第一个匹配的结果

NSString *regEx = @"<正则表达式>";
NSString *string = @"<待匹配的字符串>";
NSError *error;
NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:regEx options:kNilOptions error:&error];
if (error) {
    NSLog(@"error = %@", error);
}

NSTextCheckingResult *firstMatch = [regularExpression firstMatchInString:string options:0 range:NSMakeRange(0, string.length)];
if (firstMatch) {
    // NSTextCheckingResult 的 range 属性即匹配的字符串的位置
    NSString *matchedString = [string substringWithRange:firstMatch.range];
    NSLog(@"匹配的字符串 = %@", matchedString);       
}

获取所有匹配的结果

NSString *regEx = @"<正则表达式>";
NSString *string = @"<待匹配的字符串>";
NSError *error;
NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:regEx options:kNilOptions error:&error];
if (error) {
    NSLog(@"error = %@", error);
}

NSArray *matchArray = [regularExpression matchesInString:string options:0 range:NSMakeRange(0, string.length)];
for (NSTextCheckingResult *match in matchArray) {
    NSString *matchedString = [string substringWithRange:match.range];
    NSLog(@"匹配的字符串 = %@", matchedString); 
}

替换匹配的字符串

NSString *regEx = @"<正则表达式>";
NSString *string = @"<待匹配的字符串>";
NSString *replacingString = @"<替换的字符串>";
NSError *error;
NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:regEx options:kNilOptions error:&error];
if (error) {
    NSLog(@"error = %@", error);
}

NSString *newString = [regularExpression stringByReplacingMatchesInString:string options:kNilOptions range:NSMakeRange(0, string.length) withTemplate:replacingString];
NSLog(@"替换后的字符串 = %@", newString); 
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
java中比较两个时间的差值
项目背景1.某篇文稿的发布时间是publishDate,例如:2020072118:00:41。2.现要求判断该篇文稿的发布时间是否在近30天之内。publicstaticlongdayDiff(DatecurrentDate,DatepublishDate){LongcurrentTimecurrentDat
Stella981 Stella981
3年前
PhoneGap设置Icon
参考:http://cordova.apache.org/docs/en/latest/config\_ref/images.html通过config.xml中的<icon标签来设置Icon<iconsrc"res/ios/icon.png"platform"ios"width"57"height"57"densi
Stella981 Stella981
3年前
JS 苹果手机日期显示NaN问题
问题描述newDate("2019122910:30:00")在IOS下显示为NaN原因分析带的日期IOS下存在兼容问题解决方法字符串替换letdateStr"2019122910:30:00";datedateStr.repl
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
3年前
Runtime在iOS开发中的实际应用
运行时的文章一直被同学们热炒,当然现在面试中也都喜欢问道,当大伙说的头头是道时候,可到真正的项目中几乎局限只会关联对象或者MethodSwizzling奉为神剑到处挥砍,开发毕竟不能纸上谈兵,实践出真知,介绍目前在项目中runtime的具体使用,真切希望和各位同学探讨。1关联对象(AssociatedObject)  Catagory主要
Wesley13 Wesley13
3年前
MYSQL查询A表中不存在于B表中的所有符合条件的数据
在开发过程中,总有一些需求是需要查看在A表中ID不存在于B表中的ID的情况:下面有三种方法可以实现这一需求:第一种:使用Notin方法通过子查询的结果集来做过滤:selectfromAwhere11ANDA.IDnotin(selectIDfromB)这种情况最常见也是最容易理解的逻辑SQL代码,
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(