快速上手正则表达式

1.为毛我要写这个?

效果图
蓝色字体都是通过正则判断出来的

公司要求作出这样的效果,过去真心没有接触过。最后通过正则判断出了要去高亮的文字,但是没办法一下子去删除#话题#,或者@李小龙,中国石油(111100)这样的特定的文字。最后没有通过正则的方式,但是很庆幸,UITextView中使用正则,确实帮我们判断出了那些文字要去高亮,并且他可以在微博列表页中大显身手.

2.什么是正则?

在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。例如,我如何判断用户输入的手机号是不是正确?如何确定用户输入的邮箱是不是正确?
作用大概是两个:1.判断字符串是不是符合规则 2.过滤数据

3.基本概念

1.a-z a-z 26个小写字母
2.A-Z A-Z 26个大写字母
3.0-9 0-9之间的10个数字
4..(小数点) 匹配除了换行符以外的任意字符
5.\w 匹配除了字母或数字,下划线或者汉子
6.\s 匹配任意的空白符(包括空格,制表符(Tab),换行符,中文全角空格等)
7.\d 匹配数字
8.\b 匹配单词的开始或者结束
9.^ 匹配字符串的开始
10.$ 匹配字符串的结束
11.+ 重复一次或多次(量词)
12.? 重复零次或者一次(量词)
13.* 重复零次或者多次 (量词)
14.[],表示对一个数据进行匹配的内容(筛选范围)写在这里

4.写几个简单的正则

  • 只能匹配 a5 正则 [a][5], [a]表示这一位置只能是a,[5],这一位置只能是5.如果第一位可以是abcd中任意一个那? [a-d]或者[abcd],前者是省略写法,后者是详细写法,所以a-z表示26个字母,就不难理解了.
/**
 *  匹配 a5
 */
void test(){
    NSString *str = @"e6";
    NSString *pattern = @"a5"; //或者 [a][5],[a]5,a[5],如果这一位数据是确定的,那么我们就给他一个确定值就好,不用[]
//NSRegularExpression 正则的对象,他需要一个pattern(规则),NSRegularExpressionCaseInsensitive 是一个大小写敏感的意思(枚举)
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
                                                                           options:NSRegularExpressionCaseInsensitive
                                                                                error:nil];
//NSMatchingReportCompletion 完全匹配,该方法是获取所有匹配成功的结果,是一个数组,所以判断count == 0,就知道了是不是匹配成功
     /**
    匹配出第一个符合正则的结果
    */
   NSTextCheckingResult *r = [regex firstMatchInString:str
                                               options:NSMatchingReportCompletion
                                                 range:NSMakeRange(0, str.length)];
    /**
     匹配符合正则的数量
     */
    NSInteger count = [regex numberOfMatchesInString:str
                                             options:NSMatchingReportCompletion
                                               range:NSMakeRange(0, str.length)];
    /**
     匹配符合正则的数量,包括所有的NSTextCheckingResult 结果,一般使用第三个
     */
    NSArray *results = [regex matchesInString:str
                                      options:NSMatchingReportCompletion
                                        range:NSMakeRange(0, str.length)];
    if (results.count) {
        NSLog(@"匹配成功");
        for(NSTextCheckingResult *result in results){
            //            NSLog(@"%@",NSStringFromRange(result.range));
            NSLog(@"%@",[str substringWithRange:result.range]);
        }
    }else{
        NSLog(@"匹配失败");
    }


  • 只能匹配aH8(第一位大小写字母都行,第二位是大写,第三位是0-9) .. 一定要注意,就是\d是转义字符(有特定的含义),其中\ 斜杠在正则中有特定的含义,所以在项目中(OC)中写,\\\ 才能得到一个\,所以你看到别人写的时候,可能为了给你看起来方便,很多地方只有一个 \,但是当你写oc代码的时候,还是要有\\\,否则无效,本文全都是\\\,避免带你走入误区.
/**
 *  aH8(第一位大小写字母都行,第二位是大写,第三位是0-9)
 */
void test(){
    NSString *str = @"aH8"; 
    NSString *pattern = @"[a-zA-Z][A-Z][0-9]"; //正则 `[a-zA-Z][A-Z][0-9]`或者`[a-zA-Z][A-Z]\\d`,后者`\d`表示是0-9. 
//NSRegularExpression 正则的对象,他需要一个pattern(规则),NSRegularExpressionCaseInsensitive 是一个大小写敏感的意思(枚举)
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil];
//NSMatchingReportCompletion 完全匹配,该方法是获取所有匹配成功的结果,是一个数组,所以判断count == 0,就知道了是不是匹配成功
    NSArray *results = [regex matchesInString:str options:NSMatchingReportCompletion range:NSMakeRange(0, str.length)];
    if (results.count) {
        NSLog(@"匹配成功");
        for(NSTextCheckingResult *result in results){
            NSLog(@"%@",NSStringFromRange(result.range));
        }
    }else{
        NSLog(@"匹配失败");
    }
}
  • 匹配 adc5,或者T8,或者uy1 正则[a-zA-Z]+\\d, 这个[a-zA-Z]+的含义就是至少有一个,可以是多个英文字母,最后一位是数字
/**
 *  `adc5`,或者`T8`,或者`uy1`  
 */
void test(){
    NSString *str = @"uy1"; 
    NSString *pattern = @"[a-zA-Z]+\\d"; 
//NSRegularExpression 正则的对象,他需要一个pattern(规则),NSRegularExpressionCaseInsensitive 是一个大小写敏感的意思(枚举)
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil];
//NSMatchingReportCompletion 完全匹配,该方法是获取所有匹配成功的结果,是一个数组,所以判断count == 0,就知道了是不是匹配成功
    NSArray *results = [regex matchesInString:str options:NSMatchingReportCompletion range:NSMakeRange(0, str.length)];
    if (results.count) {
        NSLog(@"匹配成功");
        for(NSTextCheckingResult *result in results){
            NSLog(@"%@",NSStringFromRange(result.range));
        }
    }else{
        NSLog(@"匹配失败");
    }
}
  • 匹配一手机号 (第一位是1,第二位只能是356其中一个,后边随意)
    正则 1[356]\\\d{9}$ .target 13788889999
/**
 * (第一位是1,第二位只能是356其中一个,后边随意) 
 1代表着这只能是1(并不是所有的这个位置都是[],如果使用了方括号,表示是个范围,没有范围,就直接写出来就行),
`[356]`表示只能是其中一个,
`\\d{9}`,表示0-9中的数字,必须有9位,如果是`{4}`,表示有4位.  
单纯的`1[356]\\\d{9}`匹配`13788889999`是没有问题的,而且匹配`158999944443333`也是没有问题的(但这个不是一个手机号)
为什么?因为你没有指定目标文本(158999944443333)的匹配范围。
`1[356]\\\d{9}`表示,只要包含这个格式就行
^和$就是指定范围的,前者表示**匹配字符串的开始**. 后者表示**匹配字符串的结束**,
也就是说,当我们使用 `^1[356]\\\d{9}`匹配`158999944443333`是成功的,他从1开始匹配,只要前边匹配成功就好,后边的不管了,职匹配前边11位, 
当我们使用 `1[356]\\\d{9}$`匹配`158999944443333`从后边11位开始匹配,结果肯定是错误的。这样就可以匹配出正确的手机号了
 */
void test(){
    NSString *str = @"13788889999"; 
    NSString *pattern = @"1[356]\\d{9}$“
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil];
    NSArray *results = [regex matchesInString:str options:NSMatchingReportCompletion range:NSMakeRange(0, str.length)];
    if (results.count) {
        NSLog(@"匹配成功");
        for(NSTextCheckingResult *result in results){
            NSLog(@"%@",NSStringFromRange(result.range));
        }
    }else{
        NSLog(@"匹配失败");
    }
}
  • 从一个句子@"his name is wangxin,hi,I am history"里匹配出一个单词 hihis不算)
void testHi(){
    NSString *str = @"his name is wangxin,hi,I am history";
        NSString *parttern = @"\\bhi\\b";
    /**
     *  \b 是一个单词的钱或者是后,所以匹配一个单词 ,@"\\bhi\\b"; 两个斜杠,表示为了搞出一个\
     */
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:parttern options:NSRegularExpressionCaseInsensitive error:nil];
    NSArray *matchArr = [regex matchesInString:str options:NSMatchingReportCompletion range:NSMakeRange(0, str.length)];
    if (matchArr.count) {
        NSLog(@"匹配成功");
        for(NSTextCheckingResult *result in matchArr){
                        NSLog(@"range %@",NSStringFromRange(result.range));
        }
    }else{
        NSLog(@"匹配失败");
    }
}
  • 匹配一个qq号码,(5-12位)
void testQQ(){
    NSString *str = @"1512424789712129";
    /**
     NSString *str = @"1594393897987987890923";
     *  @"\\d{5,7}",代表着对字符串截取,“1594393”,@“8979879” @“878909”,三个段位,776格式的
    *   如果是@"\\d{4,5}",那么@“15943”,@“93897”,@“98798”,@“78909”,后三位不符合,直接放弃
     * 如果是@"^\\d{2,9}"(重开头获取,只一次) 159439389,其他的符合也不要
     * 如果是@"\\d{2,9}$"(冲后边可是去,只一次)987890923 其他的符合也不要
     * 如果是@"^\\d{2,9}$";意思,重头到尾,至少是2<=x<=9那么都不符合,失败
     */
    NSString *pattern = @"^\\d{5,12}$";
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil];
    NSArray *results = [regex matchesInString:str options:NSMatchingReportCompletion range:NSMakeRange(0, str.length)];
    if (results.count) {
        NSLog(@"匹配成功");
        for(NSTextCheckingResult *result in results){
            //            NSLog(@"%@",NSStringFromRange(result.range));
            NSLog(@"%@",[str substringWithRange:result.range]);
        }
    }else{
        NSLog(@"匹配失败");
    }
}
  • 匹配$a大打4 (234675)$
/**
 *  $a大打4 (234675)$, 
     "a大打4" 这个至少以为,最多4位,可以是汉子,a-z,A-Z,后边的数字是6位
      "4"  和   "("之间有空格!!
 */
void testMu(){
    NSString *str = @"$a213 123456$";
   /**
    * 1.$过去是匹配结尾,但是现在要去使用它,取消任何转义字符的时候,给他一个\就好,但是\也是一个转义字符,需要\\才行  \\$ 是 $的含义
      2.\u4e00-\u9fa5 是所有汉字的区间,但是为了更有用,前边再给他一个\  。\\u4e00-\\u9fa5
      3.\\d 同理
      4.空格符 给他一个空格代替
       5.\\d{6} 六位数字
      6.\\$同上
    */
    NSString *pattern = @"\\$[a-zA-Z\\u4e00-\\u9fa5\\d]{1,4}空格符\\d{6}\\$";
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil];
    NSArray *matchArr = [regex matchesInString:str options:NSMatchingReportCompletion range:NSMakeRange(0, str.length)];
    if (matchArr.count) {
        NSLog(@"匹配成功");
        for(NSTextCheckingResult *result in matchArr){
            NSLog(@"range %@",NSStringFromRange(result.range));
        }
    }else{
        NSLog(@"匹配失败");
    }
}

*匹配句子中的[af个]

   /**
    * 1.实际开发中,我们经常要把[哈哈]提取出来,替换成我们的表情图片,然后通过富文本替换,我么现在就去提取出来
      2.[ 是特殊转义字符,我们想把他匹配出来,使用\\[
      3.[a-zA-Z0-9\\u4e00-\\u9fa5]+ 这个位置可能使用的东西3种,至少是一个
      4.] 转义字符 \\]
    */
void testbiaqing(){
    NSString *str = @"$aaaasz123456$[魏霞]regularExpress[1234]ionW[抚松]ith[23jkadfv懂]Pattern";
    NSString *pattern = @"\\[[a-zA-Z0-9\\u4e00-\\u9fa5]+\\]";
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil];
    NSArray *matchArr = [regex matchesInString:str options:NSMatchingReportCompletion range:NSMakeRange(0, str.length)];
    if (matchArr.count) {
        NSLog(@"匹配成功");
        for(NSTextCheckingResult *result in matchArr){

            NSLog(@"%@",[str substringWithRange:result.range]);
        }
    }else{
        NSLog(@"匹配失败");
    }
}

//通过[str substringWithRange:result.range] 这个获取出[魏霞],[23jkadfv懂]等文字

5.介绍个第三方

在这里给大家介绍一个第三方 RegexKitLite,专业正则8年哈,但是他是MRC的,所以给大家介绍一下如何集成到项目中

集成RegexKitLite,建议百度一下,封装的非常好,简化了很多的方法,正的,相信我,你用的到
另一种方法

6.首尾那两个字符是表示匹配 去掉表示包含意思(三张图片)

首尾那两个字符是表示匹配 去掉表示包含意思 ^adg$adg的区别

解释1
解释2
解释3

7.特别鸣谢

参考好文章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容