世上三大最难懂:医生的处方、道士的符、程序员的正则
学了几年编程,也写了不少项目,业务逻辑经验攒了一堆,基础知识却落下不少。其中很多还非常重要,比如:进制换算、正则表达式、算法。当初学这些东西的时候,对高数的抗拒让我对带计算的东西也十分抵触。但是,身为码农,这些基础都不懂还怎么拿代码换烟钱?于是,决定恶补一下。
正则表达式
正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。 ——来自维基百科
使用场景
正则表达式起始日常生活中也用过,比如搜索的时候用的*
匹配(好吧,那个应该准确的叫做通配符,反正差不多就这意思嘛),下面谈谈正则使用的场景:
- 手机号、邮箱、
- URL判断
- 配置文件、检索关键字
- 模板引擎
使用原则
由于正则会将通常一串字符挨个检索,如果没找到匹配项,会从开头一直匹配到结尾,所以说,正则表达式的效率非常低的,能用内置函数尽量用内置函数。不过,一些特定场景正则表达式有他独有的优势。
总结:能不用就尽量不用。
语法定义
能不用就不用不代表不学习啊,万一哪天面试就考到你正则不可能瞎写一通吧。即便是做项目在网上复制的现成的也要明白个大概意思。
组成部分
其实组成部分是很多的,这里只做基础介绍。以能写出简单正则,能看懂正则意思为目的。
正则的组成:
- 定界符
- 原子
- 元字符
- 模式修正符
匹配规则:
- 从左到右
- 默认贪婪匹配(简述就是匹配成功后继续匹配,参见#贪婪模式)
定界符
定界符是正则表达式的边界,这个没有严格规定,通常以/
作为正则的定界符。规则是:不能使用0-9
、a-z
、A-Z
、\
和空格。
原子
原子在化学中讲过吧,是最小的单位。而正则中的原子同理,也是正则中最小的单位,不可再分割了。
\d
:包含0-9
\D
:不包含0-9
\w
:包含0-9
、a-z
、A-Z
和_
\W
:不包含0-9
、a-z
、A-Z
和_
\s
:包含空白字符、空格、\n
、\t
和\r
等\S
:不包含上诉空白字符\b
:词边界\B
:非词边界[]
:原子列表,可匹配列表原子或字符出串[^]
:取反,写在原子列表里为取反.
:除\n
以外任意字符
元字符
元字符是用来修饰原子的,不能单独存在,写在原子之后。
*
:匹配任意次+
:至少出现一次?
:可有可无,最多一次{}
:指定次数{10}
:指定十次{3,5}
:指定3-5次{3,}
:至少3次{0,3}
:0-3次
^
:指定以某个原子开头(千万别记混[^]
和^
的区别)\A
:与^
相同$
:指定以什么结尾\Z
:与$
相同|
:或()
:限制优先级,括号里为一个整体。子模式:参见#子模式
模式修正符
与元字符用于修饰原子,而模式修正符用于修正整个正则表达式。而模式修正符必须写在正则表达式的后面。
i
:忽略大小写m
:多行匹配s
:让.
匹配到\n
x
:忽略正则表达式中的空格A
:与\A
和^
一样U
:正则贪婪模式取反
组合
原子与不同元字符组合可以达到很多的效果,而多个元字符可以同时修饰一个原子。
.+?
:取消贪婪匹配,只匹配一个字符.*?
:取消贪婪匹配,匹配出0个字符
贪婪模式
仅从应用角度分析,可以这样认为,贪婪模式,就是在整个表达式匹配成功的前提下,尽可能多的匹配,也就是所谓的“贪婪”,通俗点讲,就是看到想要的,有多少就捡多少,除非再也没有想要的了。 ——来自[正则基础之——贪婪与非贪婪模式
](http://blog.csdn.net/lxcnn/article/details/4756030)
子模式
我们可以使用小括号给整个匹配模式进行分组,默认情况下,每个分组会自动拥有一个组号,规则是,从左到右,以分组的左括号为标志,第一个出现的分组为组号1,第二个为组号2,以此类推。其中,分组0对应整个正则表达式。对整个正则匹配模式进行了分组以后,就可以进一步使用“向后引用”来重复搜索前面的某个分组匹配的文本。例如:\1代表分组1匹配的文本,\2代表分组2匹配的文本等等 ——来自正则表达式的子模式详解
样例
由于正则的字符实在"火星",所以需要多加练习才能真正明白其匹配规则,下面写几个样例,以后需要直接用。
判断手机号
分析
手机号一般为11位纯数字,1打头,第二位号码段主要以3,4,5,7,8为主(个人猜测),第三位到最后一位为0-9的随机数。
代码
/^1[34578]\d{9}$/
判断邮箱
分析
邮箱号格式是[email protected]
,字符串中包含一个@
和一个.
,其他字符分为三段,第一段以0-9
、a-z
、A-Z
、-
和_
组成且至少一位,第二段以0-9
、a-z
、A-Z
和-
组成且至少一位,第三段以a-z
和A-Z
组成且至少两位(中文域名就算了吧)。
代码
/\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}/
总结
在实际开发中所遇到的正则无非就那么几种,网上有很多大佬写好的直接可以用,而自己写的一些正则可以存下笔记,以便以后遇到相同的需求可以直接使用,毕竟效率最重要。