正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个”规则字符串”, 这个”规则字符串”用来表达对字符串的一种过滤逻辑.
规定一些特殊语法表示字符类、数量限定符和位置关系,然后用这些特殊语法和普通字符一起表示一个模式,这就是正则表达式(Regular Expression).
给定一个正则表达式和另一个字符串,我们可以达到如下的目的:
- 1.给定的字符串是否符合正则表达式的过滤逻辑(称作”匹配”)
- 2.可以通过正则表达式,从字符串中获取我们想要的特定部分.
正则表达式的特点
- 1.灵活性、逻辑性和功能性非常的强
- 2.可以迅速地用极简单的方式达到字符串的复杂控制
正则表达式组成
- 1.字符类
- 2.数量限定符
- 3.位置限定符
字符类
.
匹配单个字符
1.可以用来匹配任何的单个字符,但是在绝大多数实现里面,不能匹配换行符;
2.它有特殊的含义,而不是字符本身的含义.如果需要匹配.
,那么要用\
进行转义,即\.
# abc. 可以匹配`abcd`,'abc9'
echo "abc9
aassds
abcdefg" | grep --color 'abc.'
[ ]
匹配一组字符
1.0-9、a-z 定义了一个字符区间,区间使用ASCII
码来确定,字符区间在[ ]
中使用.
2.- 只有在[ ]
之间才是元字符,在[ ]
之外就是一个普通字符;
3.^ 在[ ]
中是取非操作.
# [abc]d 可以匹配`ad`,`bd`,`cd`
txt="ads-dcd-ssxd-adss-1ds-ds-4ds-dsd"
echo $txt | grep --color '[abc]d'
echo $txt | grep --color '[a-z0-9]d'
echo $txt | grep --color '[^a-d^-]d'
数量限定符
数量限定符(Quantifier): 邮件地址的每一部分可以有一个或多个x字符,IP地址的每一部 分可以有1-3个y字符
1.+
匹配1
个或者多个字符
2.*
匹配0
个或者多个字符
3.?
匹配0
个或者1
个字符
4.{n}
匹配n
个字符
5.{m,n}
匹配m~n
个字符
6.{m,}
至少匹配m
个字符
7.*
和+
都是贪婪型元字符,会匹配尽可能多的内容.在后面加?
可以转换为懒惰型元字符,例如*?
、+?
和{m,n}?
txt="helllloooooooo world"
echo $txt | grep -E --color 'hel+'
echo $txt | grep -E --color 'hel*'
echo $txt | grep -E --color 'hel?'
echo $txt | grep -E --color 'hel{3}'
echo $txt | grep -E --color 'hel{3,5}'
echo $txt | grep -E --color 'hellllo{3,}'
位置限定符
字符串边界
1.^
匹配整个字符串的开头,^
元字符在字符集合中用作求非,在字符集合外用作匹配字符串的开头
2.$
匹配整个字符串的结尾
单词边界
1.\b
可以匹配一个单词的边界,边界是指位于\w
和\W
之间的位置;\b
只匹配位置,不匹配字符,因此\babc\b
匹配出来的结果为3
个字符
2.\B
匹配一个不是单词边界的位置
3.\<
匹配单词开头的位置
4.\>
匹配单词结尾的位置
txt="look at atis thisat book."
echo $txt | grep -E --color '^look'
echo $txt | grep -E --color 'ok.$'
echo $txt | grep -E --color '\bat\b'
echo $txt | grep -E --color '\bat'
echo $txt | grep -E --color 'at\b'
echo $txt | grep -E --color '\Bat'
echo $txt | grep -E --color 'at\B'
echo $txt | grep -E --color '\<at\>'
echo $txt | grep -E --color '\<at'
echo $txt | grep -E --color 'at\>'
特殊元字符
# 匹配空白字符
[\b] 回退(删除)一个字符
\f 换页符
\n 换行符
\r 回车符
\t 制表符
\v 垂直制表符
## \r\n 是`Windows`中的文本行结束标签,在`Unix/Linux`则是`\n`
## \r\n\r\n 可以匹配`Windows`下的空白行,因为它匹配两个连续的行尾标签,而这正是两条记录之间的空白行
# 数字元字符
\d 数字字符,等价于 [0-9]
\D 非数字字符,等价于 [^0-9]
# 字母数字元字符
\w 大小写字母,下划线和数字,等价于 [a-zA-Z0-9_]
\W 对 \w 取非
# 空白字符元字符
\s 任何一个空白字符,等价于 [\f\n\r\t\v]
\S 对 \s 取非
## \x 匹配十六进制字符,\0 匹配八进制,例如 \xA 对应值为`10`的`ASCII`字符,即`\n`
使用子表达式
1.使用( )
定义一个子表达式.子表达式的内容可以当成一个独立元素,即可以将它看成一个字符,并且使用*
等元字符.
2.子表达式可以嵌套,但是嵌套层次过深会变得很难理解.
3.|
是或元字符,它把左边和右边所有的部分都看成单独的两个部分,两个部分只要有一个匹配就行.
# 应用: 匹配`IP`地址
# # IP 地址中每部分都是 0-255 的数字,用正则表达式匹配时以下情况是合法的
# 一位数字
# 不以 0 开头的两位数字
# 1 开头的三位数
# 2 开头,第 2 位是 0-4 的三位数
# 25 开头,第 3 位是 0-5 的三位数
echo IP: 10.1.100.99 XXX | grep -E --color '((25[0-5]|(2[0-4]\d)|(1\d{2})|([1-9]\d)|(\d))\.){3}(25[0-5]|(2[0-4]\d)|(1\d{2})|([1-9]\d)|(\d))'
\n
回溯引用
回溯引用使用\n
来引用某个子表达式,其中n
代表的是子表达式的序号,从1
开始.
它和子表达式匹配的内容一致,比如子表达式匹配到abc
,那么回溯引用部分也需要匹配abc
.
# 应用: 匹配 HTML 中合法的标题元素
# \1 将回溯引用子表达式 (h[1-6]) 匹配的内容,也就是说必须和子表达式匹配的内容一致
echo "<h1>test</h1>" | grep -E --color "<(h[1-6])>\w*?<\/\1>"
替换
# 应用: 修改电话号码格式
# 文本: 139-1555-1234
# 在第一个子表达式查找的结果加上`()`,然后加一个空格,在第三个和第五个字表达式查找的结果中间加上`-`进行分隔
echo "139-1555-1234" | grep -E --color "(\d{3})(-)(\d{4})(-)(\d{4}) (\1) \3-\5"
# 结果: (139) 1555-1234
大小写转换
# 应用: 把文本的第二个和第三个字符转换为大写
# 文本: abcd
# 1.查找
(\w)(\w{2})(\w)
# 2.替换
$1\U$2\E$3
# 结果: aBCd
# 说明
# \l 把下个字符转换为小写
# \u 把下个字符转换为大写
# \L 把\L 和\E 之间的字符全部转换为小写
# \U 把\U 和\E 之间的字符全部转换为大写
# \E 结束\L 或者\U
前后查找
前后查找规定了匹配的内容首尾应该匹配的内容,但是又不包含首尾匹配的内容.
1.向前查找使用?=
定义,它规定了尾部匹配的内容,这个匹配的内容在?=
之后定义.所谓向前查找,就是规定了一个匹配的内容,然后以这个内容为尾部向前面查找需要匹配的内容.
2.向后匹配用?<=
定义
注: JavaScript 不支持向后匹配,Java 对其支持也不完善
# 应用: 查找出邮件地址`@`字符前面的部分
# 文本: test@qq.com
\w+(?=@)
嵌入条件
回溯引用条件
条件为某个子表达式是否匹配,如果匹配则需要继续匹配条件表达式后面的内容
# 应用: 匹配字符串被小括号包含或未包含
# 文本1: (test)
# 文本2: test
# 子表达式`(\()`匹配一个左括号,其后的`?`表示匹配`0`个或者`1`个
# `?(1)`为条件,当子表达式`1`匹配时条件成立,需要执行`)`匹配,也就是匹配右括号
(\()?test(?(1)\))
前后查找条件
条件为定义的首尾是否匹配,如果匹配,则继续执行后面的匹配.注意,首尾不包含在匹配的内容中.
# `?(?=-)`为前向查找条件,只有在以`-`为前向查找的结尾能匹配`\d{5}`才继续匹配`-\d{4}`
\d{5}(?(?=-)-\d{4})
常用的正则表达式
校验数字的表达式
# 1 数字
^[0-9]*$
# 2 n位的数字
^\d{n}$
# 3 至少n位的数字
^\d{n,}$
# 4 m-n位的数字
^\d{m,n}$
# 5 零和非零开头的数字
^(0|[1-9][0-9]*)$
# 6 非零开头的最多带两位小数的数字
^([1-9][0-9]*)+(.[0-9]{1,2})?$
# 7 带1-2位小数的正数或负数
^(-)?\d+(.\d{1,2})?$`
# 8 正数、负数、和小数
^(-|+)?\d+(.\d+)?$
# 9 有两位小数的正实数
^[0-9]+(.[0-9]{2})?$
# 10 有1~3位小数的正实数
^[0-9]+(.[0-9]{1,3})?$
# 11 非零的正整数
^[1-9]\d$
^([1-9][0-9]){1,3}$
^+?[1-9][0-9]*$
# 12 非零的负整数
^-[1-9][0-9]$
^-[1-9]\d$
# 13 非负整数
^\d+$
^[1-9]\d*|0$
# 14 非正整数
^-[1-9]\d*|0$
^((-\d+)|(0+))$
# 15 非负浮点数
^\d+(.\d+)?$
^[1-9]\d.\d|0.\d[1-9]\d|0?.0+|0$
# 16 非正浮点数
^((-\d+(.\d+)?)|(0+(.0+)?))$
^(-([1-9]\d.\d|0.\d[1-9]\d))|0?.0+|0$
# 17 正浮点数
^[1-9]\d.\d|0.\d[1-9]\d$
^(([0-9]+.[0-9][1-9][0-9])|([0-9][1-9][0-9].[0-9]+)|([0-9][1-9][0-9]))$
# 18 负浮点数
^-([1-9]\d.\d|0.\d[1-9]\d)$
^(-(([0-9]+.[0-9][1-9][0-9])|([0-9][1-9][0-9].[0-9]+)|([0-9][1-9][0-9])))$
# 19 浮点数
^(-?\d+)(.\d+)?$
^-?([1-9]\d.\d|0.\d[1-9]\d|0?.0+|0)$
校验字符的表达式
# 1 汉字
^[\u4e00-\u9fa5]{0,}$
# 2 英文和数字
^[A-Za-z0-9]+$
^[A-Za-z0-9]{4,40}$
# 3 长度为3-20的所有字符
^.{3,20}$
# 4 由26个英文字母组成的字符串
^[A-Za-z]+$
# 5 由26个大写英文字母组成的字符串
^[A-Z]+$
# 6 由26个小写英文字母组成的字符串
^[a-z]+$
# 7 由数字和26个英文字母组成的字符串
^[A-Za-z0-9]+$
# 8 由数字、26个英文字母或者下划线组成的字符串
^\w+$
^\w{3,20}$
# 9 中文、英文、数字包括下划线
^[\u4E00-\u9FA5A-Za-z0-9_]+$
# 10 中文、英文、数字但不包括下划线等符号
^[\u4E00-\u9FA5A-Za-z0-9]+$
^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
# 11 禁止输入含有~的字符
[^~\x22]+
特殊需求表达式
# 1 Email地址
^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$
# 2 域名
[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
# 3 InternetURL
[a-zA-z]+://[^\s]
^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=])?$
# 4 手机号码
^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$
# 5 电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX")
^((\d{3,4}-)|\d{3.4}-)?\d{7,8}$
# 6 国内电话号码(0511-4405222、021-87888822)
\d{3}-\d{8}|\d{4}-\d{7}
# 7 身份证号(15位、18位数字)
^\d{15}|\d{18}$
# 8 短身份证号码(数字、字母x结尾)
^([0-9]){7,18}(x|X)?$
^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$
# 9 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线)
^[a-zA-Z][a-zA-Z0-9_]{4,15}$
# 10 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线)
^[a-zA-Z]\w{5,17}$
# 11 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间)
^(?=.\d)(?=.[a-z])(?=.*[A-Z]).{8,10}$
# 12 日期格式
^\d{4}-\d{1,2}-\d{1,2}
# 13 一年的12个月(01~09和1~12)
^(0?[1-9]|1[0-2])$
# 14 一个月的31天(01~09和1~31)
^((0?[1-9])|((1|2)[0-9])|30|31)$
# 15 xml文件
^([a-zA-Z]+-?)+[a-zA-Z0-9]+\.[x|X][m|M][l|L]$
# 16 中文字符的正则表达式
[\u4e00-\u9fa5]
# 17 双字节字符
# 包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)
[^\x00-\xff]
# 18 空白行的正则表达式
# 可以用来删除空白行
\n\s*\r
# 19 HTML标记的正则表达式
<(\S?)[^>]>.?\1>|<.?/>
# 20 首尾空白字符的正则表达式
# 可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式
^\s|\s$或(^\s)|(\s$)
# 21 腾讯QQ号
# 腾讯QQ号从10000开始
[1-9][0-9]{4,}
# 22 中国邮政编码
# 中国邮政编码为6位数字
[1-9]\d{5}(?!\d)
# 23 IP地址
# 提取IP地址时有用
\d+.\d+.\d+.\d+
((?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))