正则表达式书写规则说明,正则表达式规则详解

  • A+
所属分类:技术分享

正则表达式书写规则说明,正则表达式规则详解

一、说明

我曾经看过无数的正则表达式文章,然而每当我再次需要书写仍然感觉无从下手,一如既往需要百度“IP正则表达式”、“URL正则表达式”。

反思这种现像的原因,一是很多文章都是授之以鱼的比如直接告诉你URL的正则表达式是“[a-zA-z]+://[^\s]*”,而且同一个表达式(比如都是URL正则表达式)不同的文章给出的经常是不一样的(其原因一是有的考滤比较全有的考滤没有那么全二是正则表达式确实就是有很多等价写法)。这没法记。

二是授之以渔的教程大多都只是把官方文档搬过来,大而全没突出关键点,这也没法记。

 

二、正则书写关键点

正则书写的关键点只有三个:一是所有基础表达式默认都能且只能匹配一个字符,二是除非其后给出限定符另外指出匹配次数,三是限定符只限定在其前面的那一个表达式(^定位符只对其后一个表达式生效,$定位符只对其前一个表达式生效)。

2.1 基础表达式

可打印字符基础表达式:

基础表达式 说明
a 单个字符。a这里只是个代表,可以是任意非特殊字符
a|b 匹配a或b。a和b只是个代表,a和b可以是任意非特殊字符
[abc] 匹配a或b或c。a、b和c只是个代表,a、b和c可以是任意非特殊字符
[^abc] 匹配不是a或b或c以外的所有字符。
[a-z] 匹配a到z的任意一个字符
\d 匹配一个数字字符。等价于 [0-9]。
\D 匹配一个非数字字符。等价于 [^0-9]。
\w 匹配字母、数字、下划线。等价于'[A-Za-z0-9_]'。
\W 匹配非字母、数字、下划线。等价于 '[^A-Za-z0-9_]'。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。

非打印字符基础表达式:

基础表达式 说明
\cx 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。
\f 匹配一个换页符。等价于 \x0c 和 \cL。
\n 匹配一个换行符。等价于 \x0a 和 \cJ。
\r 匹配一个回车符。等价于 \x0d 和 \cM。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\t 匹配一个制表符。等价于 \x09 和 \cI。
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。

 

特殊字符基础表达式(特殊字符是指正则中用他来做别的功能他不能是他自己的字符):

特殊字符 特殊字符基础表达式
$ 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身,请使用 \$。
( ) 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。
* 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。
+ 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。
. 匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \. 。
[ 标记一个中括号表达式的开始。要匹配 [,请使用 \[。
? 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。
\ 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\",而 '\(' 则匹配 "("。
^ 匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示除了该字符以外的所有字符的集合。要匹配 ^ 字符本身,请使用 \^。
{ 标记限定符表达式的开始。要匹配 {,请使用 \{。
| 指明两项之间的一个选择。要匹配 |,请使用 \|。
- 表示字符范围是从其前边的那个字符到其后边的那个字符。要匹配-请使用\-。

 

 

2.2 限定符

限定符 说明
* 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
? 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 、 "does" 中的 "does" 、 "doxy" 中的 "do" 。? 等价于 {0,1}。
{n} n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。
{n,} n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。
{n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。

 

2.3 一些说明

[]和()的区别是,[]中只能是匹配单个字符而不能是匹配多个字符的表达式,更不能是子表达式。

正则表达示一用于查找符合某种模式的字符串,而不擅长查找不符合某种模式的字符串;在shell脚本中如果要查找不匹配的字符串,那可以使用grep -v。

 

三、正则表达式示例

理解别人的正则表式比自己写正则表达式更能代表对表代式的掌握程度,我们以这个网站生成的几个表达式进行解析。抓住上面说的三大关键点基本都能够理解。

 

3.1 URL正则表达式

表达式:[a-zA-z]+://[^\s]*

[a-zA-z]+----[a-zA-z]是一个基础表达式,意思是匹配任意小写或大写字母(A-z的z应该是错的应该大写才是其本意)。+是其限定符,所以他不再是只能匹配一次而是一次或多次。

://----这是三个基础表达式(:和/和/),由于他们都没有限定符,所以他们各自都能且只能匹配一次。

[^\s]*----[^\s]是一个基础表达式表示所有非空白字符。*是其限定符,所以他不再是只能匹配一次而是可以是任意次。

总的来看这个表达式是一个很不严谨的URL表达式。

 

3.2 身份证正则表达式

表达式:^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$

^(\d{6})----^表示(\d{6})在开头匹配,\d表示数字,{6}表示\d要且只要匹配6次。(省市县)

(\d{4})----\d表示数字,{4}表示\d要且只要匹配4次。(年)

(\d{2})----\d表示数字,{2}表示\d要且只要匹配2次。(月)

(\d{2})----\d表示数字,{2}表示\d要且只要匹配2次。(日)

(\d{3})----\d表示数字,{3}表示\d要且只要匹配3次。(编号)

([0-9]|X)$----$表示([0-9]|X)在末尾匹配,没有限定符所以([0-9]|X)能且只能匹配一个字符,该字符要么是0到9中的一个要么是字母“X”。(校验码)

 

3.3 ip正则表达式

表达式:^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.(([1-9]|[1-9][0-9])|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$

 

四、正则在线生成及测试工具

站长之家:http://tool.chinaz.com/regex/

菜鸟教程:https://c.runoob.com/front-end/854

开源中国:http://tool.oschina.net/regex/#

五、GNU正则表达式

5.1 linux为什么不使用标准正则

linux的很多文本编缉命令支持正则表达式,比如grep、sed等。但有时我们可能会发现在第四大点能匹配出结果的正则,放到grep中却匹配不出来。

这是因为grep等命令使用的正则和广泛使用的正则不一样,若要问“linux为什么不使用标准正则”这类问题,那就要从正则表达式的历史说起。

正则表达示的概念最早由美国数学家 Stephen Cole Kleene在1951年提出,其后正则的形式不断丰富,UNIX实现时其携带的vi、sed、awk等命令都支持正则表达式。

UNIX命令本身支持的正则表达式是一致的,且1992年被标准化到POSIX中;Linux遵从POSIX所以正则也基本依照UNIX实现。

然而在操作系统之外,正则表达式还是在不断发展的并不依照POSIX去实现,其中影响最广泛的就是Perl的PCRE(Perl Compatible Regular Expressions),Java、JavaScript、Python、Ruby、Qt、 .NET及 XML Schema等大量语言都参照PCRE实现。PCRE也因此成为了“标准正则”,而UNIX/Linux命令使用的正则就沦为了“非标准正则”。

 

5.2 GNU正则表达式和标准正则的区别

分类:基本正则表达式(Basic Regular Expressions or BRE)和扩展正则表达式(Extended Regular Expressions or ERE)。

使用:ed、grep、sed等命令使用BRE(但grep可通过-E、sed可通过-r使用ERE);egrep、awk、emacs等工具使用ERE。

区别:BRE中单独的?+(){}不是特殊字符,如果要想表示特殊含义需要在其前面加反斜杠;ERE则正好相反,单独的?+(){}这几个符号是特殊字符(和“标准正则”一样),在其前加反斜框则表示字符本身。ERE较BRE更类似“标准正则”类似,但ERE和“标准正则”也不是完全一样。