开发必备技能之正则表达式详解

正则表达式

序言
好久没写过文章啦,距离自己上一次的记录已经过去了半年多了,也许是工作忙了,也许是自己懒惰了,也许是...最近的工作不怎么忙,心就想着要写点什么呢,由于同事的几句话,真的"机缘巧合"的写了这个知识,虽然这个知识点有点陈旧哈,但我相信对于那些对正则刚入门初学的开发者来说,你认真看过这篇文章之后,对于正则的认识、语法规则必会有一个大大提升的,若再附加自己的实践,相信你对于掌握好这个知识点是没有什么问题的哈,

含义

是由普通字符(字符 a 到 z)以及特殊字符("元字符")组成的文字模式(即字符串文本的复杂处理(查找、匹配、验证))

核心

正则表达式的语法规则

原则

尽可能罗列出所有出现的情况,然后再按照罗列的字符串写出符合要求的正则表达式,尽可能的精确匹配

建议

虽然现在常见的正则表达式我们都可以查到,但还是应该对正则语法有一些认识,不可生搬硬套别人的正则表达式

普通字符

包括没显式指定为元字符的所有可打印和不可打印字符(所有大写和小写字母、所有数字、所有标点符号和一些其他符号)

特殊字符

若匹配这些特殊字符,须先使用转义字符\放在它们前面

几点说明

  • 匹配包括 '\n' 在内的任何单字符 - [.\n]
  • 选择符|一般结合非捕获元字符?:和分组()搭配使用,因为它的优先级最低
  • 分组()是对于复杂的文本分割成子表达式使用,一般结合反向引用\n使用,这时编号是按照左括号往右的一次叠加的,即:编号从 1 开始,最多可存储 99 个捕获的子表达式,场景: 匹配重复出现的字符串
  • 中括号表达式(字符簇)[],表示所有字符的字符簇(集合),若在中括号表达式中包括连字符-,则需要用反斜扛将它转义,但是若将连字符放在中括号列表的开始或结尾,则不需反斜扛转义

非打印字符

下图列出了非打印字符的转义序列


限定符

限定符用来指定正则的一个子表达式出现多少次能满足匹配,共6种


几点说明

  • 限定符*+?都是贪婪的,它们会尽可能多的匹配所搜索的字符串,只有在它们的后面加上一个?就可以实现非贪婪或最小匹配
  • 即: ?放在任何一个其他限定符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的,非贪婪模式会尽可能少的匹配所搜索的字符串(比如:对于字符串 "chongzoneeeee",'e+?' 将匹配单个 "e",而 'e+' 将匹配所有 'e'),场景:检测字符串是否包含某个字符等

定位符

定位符使您能够将正则固定到行首或行尾


注意点
不能将限定符与定位符一起使用,因为在紧靠换行或字边界的前面或后面不能有一个以上位置

预搜索(零宽断言assert)

零宽断言是对位置的匹配,共4种(下图列出了常见的2种)

几点说明

  • (?:pattern) - 分组虽然使匹配更加清晰,但同时会产生一个副作用,使相关的匹配被缓存(存储到一个临时缓冲区中),此时使用?:放在分组选项前可消除这种副作用,不捕获匹配的文本,即:不给分组分配组号,则此时对于重复的字符串就不能使用反向引用
  • (?=pattern) - 匹配以pattern结尾的前面的部分字符串,不包括pattern部分
  • (?<=pattern) - 匹配以pattern开头的后面的部分字符串,不包括pattern部分
  • (?!pattern) - 断言位置的后面不能匹配表达式pattern
  • (?<!pattern) - 断言位置的前面不能匹配表达式pattern

即: (?=pattern)(?!pattern)放在后面,(?<=pattern)(?<!pattern)放在前面,场景: 取出需要的字符串

反向引用

反向引用用于重复搜索前面某个分组匹配的子表达式,当然也可以自己指定子表达式的组名
语法规则
(?<name>\w+)(或':(?'name'\w+)),这样组名\w+的就定为name,若是反向引用这个分组,则使用\k<name>,即: \b(?<name>\w+)\b\s+\k<name>\b

其他元字符

不常用的其他元字符

  • 模式修改符 - (?i)开 和 (?-i)关 - 包含区域不区分大小写 - 不建议使用
  • 注释 - (?#comment),对于不熟悉的匹配规则可以使用

运算符的优先级

下表从上到下列出了优先级最高到最低的排序



常用的正则表达式

写到这里的时候,自己呢本是不想写这个常用正则表达式部分的,但基于我看到的其他开发者写的或归纳整理的正则表达式,大部分都是COPY下来的,里面的有些正则表达式明显是有错误的...这样传阅下来估计会误导不少初学者呢,虽然对客户端开发者来说,正则使用的不是很频繁,在开发中用到的也就那么几种,现在的互联网这么发达,百度谷歌下不就知道啦,当然了还有另一个原因,由于正则的语法比较繁琐,时间一长不经常使用的话难免有些正则会被遗忘的,这样整理的话自己以后使用也是很方便的,好记性比不上烂笔头嘛,哈哈,废话就不多说了,有什么写的不对的地方请多多交流哈(ノへ ̄、)

1.用户名(首字母,长度6-16)

"^[a-zA-Z]\\w{5,15}$"

2.表单密码(长度6-16)

"^\\.{6,16}$"

3.验证码(长度6)

"^\\d{6}$"

4.固话号码(首数字0)

"^0\\d{2,3}-\\d{7,8}$"

5.手机号码(长度11)

"1|[34578]\\d{9}"

6.银行卡号(长度16-19)

@"^\\d{16,19}$"

7.身份证号(长度18,长度15已淘汰)

"^\\d{17}[\\dxX]$" 

8.Email地址(.com、.cn等)

 "^\\w+@\\w+(\\.[a-zA-Z]{2,3}){1,2}$"

9.仅含数字

"^\\d+$”

10.仅含字母

"^[a-zA-Z]+$"

11.仅含数字和字母

"^[0-9a-zA-Z]+$"

12.整数

"^\\-?\\d+$"

13.小数

"^\\d+\\.\\d*$"

14.浮点数

"^\\-?\\d+\\.?\\d*$"

15.正整数(最小1)

"^\\+?[1-9]\\d+$"

16.负整数(最大-1)

"^\\-[1-9]+$"

17.n位的小数

"^\\d+\\.\\d{n}$"

18.月份(长度1\2)

"^(0?[1-9]|1[0-2])$"

19.日数(最大31)

"^((0?[1-9])|((1|2)[0-9])|30|31)$"

20.含空白行

"\\s*"

21.首位空白符

"^\\s+|\\s+$"

22.含双字节

"[^\x00-\xff]"

23.包含中文(检测工具不支持)

"[\\u4e00-\\u9fa5]+"

24.搜索叠词

"\\b([a-z]+) \1\\b"

25.含n个字母的单词

"[[:alpha:]]{n}"

26.中国邮编(长度6)

"^[1-9]\\d{5}$"

27.QQ号码(最小5位,目前最大10位)

"^[1-9]\\d{5}$"

28.HTML标签

 "<\\s*(\\S+)(\\s[^>]*)?>[\\s\\S]*<\\s*\\/\\1\\s*>"

29.网络URL(附带端口号匹配)

"http(s?):\\/\\/([^\\/:]+)(:\\d*)?([^ ]*)"

30.网页图片

"\\< *[img][^\\\\>]*[src] *= *[\\"\\']{0,1}([^\\"\\'\\ >]*)"

31.IP地址

"^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"

iOS开发中的使用

在iOS开发中,Cocoa框架给我们提供了谓词NSPredicate类,类似过滤器的作用,就相当于SQLwhere条件,在iOS开发中,我们常用的做法将谓词和正则表达式配合使用,代码如下:

/**
 * 匹配字符串
 *
 @param inputText 输入的文本
 @param validRegular 正则表达式
 @return YES 匹配成功 NO 匹配失败
 */
- (BOOL)verifysInputText:(NSString *)inputText validRegular:(NSString *)validRegular {
    NSPredicate *predicte = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",validRegular];
    return [predicte evaluateWithObject:inputText];
}

结束语

最后呢,推荐给大家一个在线的正则表达式检测工具Regex101,当然在Mac端,你也可以下载一个客户端RegExRx,不过它不是免费的,需要30块大洋,但它的界面简洁,为了学习嘛,都懂的,当然你也可以下载个破解版...
(ps:在检测工具内,单斜杠\不需要转为双斜杠\\,因为只有在代码中,编译器是默认单斜杠为转义字符,需要你转为双斜杠,所以上面你 看到的代码全是双斜杠的\\,还有就是基本常见的检测工具都是不支持检测中文输入的,因为不能识别 "\u" 字符)

对于这个知识点、文章有什么不太理解的地方,还请在下面留言,看到之后有时间会回复的... 午安。。。

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

推荐阅读更多精彩内容