1.入门
正则表达式(regular expression,简称regex)是一种工具,用于匹配和处理文本的字符串。
正则表达式并不是一种完备的程序设计语言,甚至算不上是一种能够直接安装并运行的程序。
本文针对 [grep -P]
1.1匹配单个字符
匹配纯文本
text : hello,world!!
regex : hello
output : hello
匹配任意字符
text : sale1.xls
sale2.xls
na1.xls
regex : sale
output : [sale]1.xls
[sale]2.xls
’ . '字符可以匹配任意单个的字符、字母、数字和本身。
text : sale1.xls
sale2.xls
na1.xls
regex : sale.
output : [sale1].xls
[sale2].xls
’ . ‘字符本身而不是它在regex中的特殊含义,需要’ \ ‘进行转义,而匹配’ \ ‘本身也需要转义。’ \ ‘字符永远出现在一个有着特殊含义的字符序列的前面。这个序列可由一个或多个字符构成。
##1.2匹配一组字符
’ [ 一组字符] ’ 用来匹配一组字符而匹配’ [ ‘和’ ] '本身,则需要转义。
text : sale1.xls
sale2.xls
na1.xls
regex : [a-z][0-9]
output : sal[e1].xls
sal[e2].xls
n[a1].xls
模式[0-9]与[0123456789]完全一样,连字符’ - ‘只在’ [ ] '中有特殊意义,需要转义,在外面是普通字符。
’ ^ '表明取非匹配。
1.3元字符
空白字符
[\b] 回退
\f 换页符
\n 换行符
\r 回车符
\t 制表符
\v 垂直制表符
字符集元字符
\d 数字
\D 非数字
\w 字母、数字、_
\W 非\w
\s 空白字符集
\S 非\s
十六进制
\x开头
八进制
\0开头
POSIX字符类
[:alnum:] == [a-zA-Z0-9]
[:alpha:] == [a-zA-Z]
[:cntrl:] == [\t ]
[:digit:] == [0-9]
[:graph:] == [:print:]一样,但不包含空格
[:lower:] == [a-z]
[:print:] == 可打印字符
[:punct:] == ^[[:alnum:][:cntrl:]]
[:space:] == 空字符集,含空格
[:upper:] == [A-Z]
[:xdigit:] == [a-fA-F0-9]
1.4重复匹配
' + ' ' * '表明重复匹配
' + ' 匹配一个或多个字符(至少一个)
' * ' 匹配0个或多个字符
' ? ' 匹配0个或1个,即可选
text : www.baidu.com
xxx.asd@163.com
regex : \w+\.\w+\.\w+
output : [www.baidu.com]
regex : [\w.]+@\w+\.\w+
output : [xxx.asd@163.com]
1.5重复匹配次数
'{num}' 表示重复匹配num次
regex : [\w]{3}
等价
regex : [\w][\w][\w]
'{num1,num2}'表示重复匹配至少num1次,最多num2次
'{num,}'表示至少重复num次,无上限
1.6贪婪型元字符
text : asdfa <B>asdfa</B> asd <B>asd</B>
regex : <B>.*</B>
output ; asdfa [<B>asdfa</B> asd <B>asd</B>]
//把asd也匹配了,贪婪型元字符,会尽可能的从开头一直匹配到结尾。
regex : <B>.*?</B>
output ; asdfa [<B>asdfa</B>] asd [<B>asd</B>]
贪婪型元字符 | 懒惰型元字符 |
* | *? |
+ | +? |
{n,} | {n,}? |
1.7位置匹配
边界
text : the cat scatted his food all over the room.
regex : cat
output : the [cat] s[cat]ted his food all over the room.
将文本中所有cat都找了出来,这是没有意义的
单词边界
1.由限定符\b指定的单词边界,\b即是空格。
2.\B则是非\b,匹配前后都不是单词边界的单词。
字符串边界
^\s* 匹配一个字符串的开头位置和随后0个或多个空白字符。
\s*$ 匹配一个字符串的结尾和随后0个或多个空白字符。¥
分行匹配
$不仅能匹配字符串结尾,还将匹配行分隔符(换行符)后面的结束位置。
1.8子表达式
’ ( ) '把一个表达式当作一个元素
  非换行空格符
{2,}
匹配 ;;;; ...
( ){2,}
匹配 ( ){2,}( ){2,}( ){2,} ...
子表达式允许多重嵌套使用。
1.9回溯引用
子表达式把一组字符编组为一个字符集合。
主要用于精确设定需要重复匹配的文本及其重复次数。
子表达式的另一个重要用途就是回溯引用(backreference)。
例如在HTML中
regex1 : <Hh1>.*</Hh1> 只能匹配一级标题
regex2 : <Hh[1-6]>.*</Hh[1-6]> 匹配1-6级标题,但是它还可以匹配<Hh2>.*<Hh3>这种错误标题。
text : this is block of of text,
several words here are are
repeated, and and they
should not be.
regex : [ ]+(\w+)[ ]+\1
output : this is block [of of] text,
several words here [are are]
repeated, [and and] they
should not be.
## \1 是回溯引用,引用前面划分出来的子表达式
可将regex2写为
<[hH]([1-6])>.*?</[hH]\1>
\1 第1个子表达式
...
\5 第5个子表达式
\0 代表整个regex
1.10回溯引用用于替换
需要两个regex,一个给出搜索模式,一个给出匹配文本替换模式。
text : 313-555-1234
314-555-1324
311-555-1234
regex : (\d{3})(-)(\d{3})(-)(\d{4})
替换 : ($1) $3-$5
output : (313) 555-1234
(314) 555-1324
(311) 555-1234
1.11前后查找
向前查找指定了一个必须匹配但不在结果中返回的模式,其实就是一个子表达式,从语法上看,以?=开头的子表达式,需要匹配的文本跟在=后面。
text : http://1231
https://123132
ftp://1231
regex : .+(?=:)
output : [http]://1231
[https]://123132
[ftp]://1231
向后查找,以?<=开头的子表达式。与向前查找放的位置相反。
还可以组合进行,前后查找。
1.12嵌入条件
regex里条件用?定义。
?匹配一个字符或表达式。
?=和?<=匹配前面或后面的文本。
回溯引用条件
语法 (?(backreference)true-regex)
?表明是一个条件,backreference是一个回溯引用,true-regex是一个backreference存在时才会被执行的子表达式。
regex : (<A\s+[^>]+>\s*)?img\s+[^>]+>(?(1)\s*</A>)
(<A\s+[^>]+>\s*)?这个标签可有可无,因为后面有个?,只有当它存在时,才匹配(?(1)\s*</A>)
前后查找条件
只在一个向前或向后查找操作取得成功时,才允许一个表达式被使用。
regex : \d{5}(-\d{4})?
匹配5个数字[-4个数字]
regex : \d{5}(?(?=-)-\d{4})
(?=-)用来匹配一个 - 字符,如果存在则匹配4个数字