正则表达不再靠control+v(实操篇)

1. 前言

  • 前面的正则的基础语法了解之后,正式开始实际应用
  • 对基础知识感兴趣的可以看看我写的基础篇 《正则表达不再control+v》
  • 结尾有一些常用的正则表达式,但是想了解为什么还是最好顺序阅读
    awesome.JPG

2.子表达式

2.1 概念

  • ()括起来的就是子表达式
  • 我的理解:子表达式的目的是为了增加匹配的优先级,子表达式内的优先级较高,优先匹配
  • 子表达式可以嵌套,这个在下面会通过例子来解释

2.2 实战-IP地址的匹配

  • 我们会一步一步完善和简化一个IP的正则表达式

  • 需求分析:IP 地址是由.分隔的四组数字,如192.168.1.106。因为每个部分的数字都可以为1-3位数字字符

    IP地址匹配1.0.png

  • 分析

    first:\d{1,3}表示匹配一个由数字组成的1-3位的字符串
    second:\d{1,3}\.表示1-3位数字,并以.结尾
    third:最后一组字符串不需要以.结尾,所以\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}貌似可以解决IP的匹配

  • 但是d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}这个正则,重复表达式太多,垃圾代码那么多能忍么???那么子表达式就出现用处了

    IP地址匹配1.0-子表达式简化版.png

  • 分析

    \d{1,3}\.()子表达式括起来,并加上重复执行次数,能简化正则的可阅读性

  • 那么我们的IP正则的容错性到底怎么样?


    IP地址匹配-非法IP校验.png
  • 非法IP也能被匹配,说明我们的IP匹配有问题,其实是需求分析有问题,IP的地址规则并未完全体现,那么补充需求之后再完善我们的IP地址匹配吧

IP地址规则:

  1. 所有的一位数和两位数
  2. 三位数的第一位为 1
  3. 如果三位数的第一位为 2 ,且第二位从 0 到 4
  4. 如果三位数的前二位为 25 ,且第三位从 0 到 5
  5. 总结:0-255.0-255.0-255.0-255 就是我们要写的
  • 明确了规则,把每条规则实现即可


    IP地址匹配2.0.png
  • 新的实现(((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5])),一个匹配里嵌套了四组子表达式

解析:
1.将整个正则拆成两个部分((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5])),前一部分重复三次用来表示前面三组数字,并且以.结尾,后一部分表示最后一组IP地址
2.第一部分:(\d{1,2}),这个子表达式将匹配一位或者两位任意数字
3.第二部分:((1\d{2}),这个子表达式将匹配以1开头的后两位任意数字的三位数字
4.第三部分:(2[0-4]\d),这个子表达式将匹配以2开头的中间一位为0-4,第三位为任意数字的字符串
5.第四部分:(25[0-5]),这个子表达式将匹配以25开头的尾数为0-5的三位数字

  • 还有网上很多别的写法,但是我觉得这个写法是比较好理解的版本,所以如果有更好的,可以告诉我,毕竟我觉得真的很长

2.3 年份匹配

  • 这个需求很简单,就是匹配19xx-20xx所有年份
  • 目的:体验子表达式的优先级
  • 实用性:我觉得这种简单的正则在开发中实用性很强,很多都可以用到
    年份匹配-错误版本.png
  • 解释

1.19|20\d{2}这个表达式没有达到我们的效果
2.这个表达式其实的效果是匹配19(两位)和以20开头的四位数字
3.这里就能体现子表达式的效果,我们想要的是19或者20开头的四位数字,那么我们完全可以这部分用子表达式括起来,来实现效果

年份匹配-正确版本.png

2.4 HTML标签匹配

  • 需求:匹配H5标签,因为H5标签的格式还是很固定的<xxx>xxx</xxx>
  • 知识点:这里会用到向后引用这个写法
  • 以匹配H标签为例


    标签匹配-错误版.png
  • 这里就有个需求就是前面和后面的相同匹配规则匹配保持一致,比如前面匹配了H2标签,后面还是要匹配H2标签,前后一致

2.4.1 后向引用

  • 后向引用就是引用前面的子表达式
  • 使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其他程序中作进一步处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推
  • 后向引用用于重复搜索前面某个分组匹配的文本
  • 可以参考文章: 正则表达式后向引用~~~~~~ & 正则表达式后向引用

2.4.2 HTML标签匹配之向后引用

  • 但是我这里遇到了个问题:使用Regextor出现了不能匹配正确的向后引用,我不确定是APP不能识别这种语法还是什么原因,如果有知道请告诉我
    Regextor不支持向后引用么?.png
  • 我们在xcode中使用了匹配查询,这个正则完全能达到我们的要求


    xcode匹配结果.png
  • <[hH]([1-5])>.*?</[hH]\1>分析

<[hH]([1-5])>中将第一个子表达式使用()括起来,在缓存中使用这个子表达式默认为第一个分组
</[hH]\1>\1使用第一个的子表达式的匹配取值应用到第二处,不如前面匹配了1,后面只能匹配1

3,实际开发应用

3.1 查找替换文本

  • 2.4.2 HTML标签的匹配中就用xcode的查找操作


    xcode匹配.png

3.2 校验字符串是否符合规则-NSPredicate

  • 最常用的一种方式
NSString *string = @"hotCat";
//正则
NSString *regex = @"^ho[a-zA-Z]{2,}*$";
//创建NSPredicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
BOOL result = [predicate evaluateWithObject:string];

3.3 字符串某一个字符或者字符集的定位

  • 用处:特定的字符串的替换,或者某些字符的删除,都可以使用,因为可以拿到想要的NSRange
NSString *string = @"hotCat123";
//使用正则\d+去string中进行匹配,得到的时匹配到的range,在这里为{4,3}。
NSRange range = [string rangeOfString:@"\\d+" options:NSRegularExpressionSearch];
//如果匹配到就打印匹配到的子字符串,在这里为123。
if (range.location != NSNotFound)
{
    NSLog(@"%@",[string substringWithRange:range]);
}

分析:
1.\d+用来查找数字
2.rangeOfString:options:会返回一个NSRange,用来接收匹配的范围options必须要用NSRegularExpressionSearch,代表用正则去匹配
3.当写正则字符串时,\需要写成\\ ,所以,\d+需要写成\\d+

3.4 NSRegularExpression

  • NSRegularExpression这个类可以用户来查找字符串中符合要求的第一个匹配结果或者所有匹配结果
  • 这个使用很简单,就不详细介绍了,如果有想知道使用的,可以移步oc中正则表达式NSRegularExpression类详解

3.5 其它

  • 我觉得还可以有很多高级的用处,但是实际开发中还没遇到,如果有遇到可以告诉我,我会去在深入学习下,谢谢啦!!!

4. 最后的福利

  • 最后的留一些常用的校验吧,以免有人偷懒,所以写在最后,但是可能不知道是否符合最新的标准,比如手机号码,新字段开发太快了
/**
     * 手机号码:
     * 13[0-9], 14[5,7], 15[0, 1, 2, 3, 5, 6, 7, 8, 9], 17[0, 1, 6, 7, 8], 18[0-9]
     * 移动号段: 134,135,136,137,138,139,147,150,151,152,157,158,159,170,178,182,183,184,187,188
     * 联通号段: 130,131,132,145,155,156,170,171,175,176,185,186
     * 电信号段: 133,149,153,170,173,177,180,181,189
     */
    NSString *MOBILE = @"^1(3[0-9]|4[57]|5[0-35-9]|7[0135678]|8[0-9])\\d{8}$";
    /**
     * 中国移动:China Mobile
     * 134,135,136,137,138,139,147,150,151,152,157,158,159,170,178,182,183,184,187,188
     */
    NSString *CM = @"^1(3[4-9]|4[7]|5[0-27-9]|7[08]|8[2-478])\\d{8}$";
    /**
     * 中国联通:China Unicom
     * 130,131,132,145,155,156,170,171,175,176,185,186
     */
    NSString *CU = @"^1(3[0-2]|4[5]|5[56]|7[0156]|8[56])\\d{8}$";
    /**
     * 中国电信:China Telecom
     * 133,149,153,170,173,177,180,181,189
     */
    NSString *CT = @"^1(3[3]|4[9]|53|7[037]|8[019])\\d{8}$";


邮箱:   ^[a-zA-Z0-9]{4,}@[a-z0-9A-Z]{2,}\\.[a-zA-Z]{2,}$
大陆固定电话号码:    ^\\d{4}-|\\d{3}-)?(\\d{8}|\\d{7}$
身份证号:    \\d{14}[[0-9],0-9xX]
Email地址:    ^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\.\\w+([-.]\\w+)*$
纯数字:   ^[0-9]*$
由数字和英文字母组成:   ^[A-Za-z0-9]+$
QQ号:   ^[1-9][0-9]\{4,\}$
中国邮政编码:   ^[1-9]\\d{5}(?!\\d)$
URL:  ^http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?$
纯汉字中文:^[\u4e00-\u9fa5]{0,}$

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

推荐阅读更多精彩内容