【网络运维】Linux:正则表达式
Linux 正则表达式
正则表达式是一种强大的文本匹配工具,它使用特定的模式来搜索、匹配和操作字符串。在Linux环境中,正则表达式被广泛应用于各种工具(如grep、sed、awk等)和编程语言中。
本文将全面介绍Linux正则表达式的基本概念和用法。
正则表达式基础
正则表达式由普通字符和元字符组成:
- 普通字符:包括所有字母、数字、标点符号等可打印字符
- 元字符:具有特殊含义的字符,如
.
、*
、^
等
正则表达式可分为两类:
- 普通正则表达式(Basic Regular Expressions)
- 扩展正则表达式(Extended Regular Expressions),支持更多元字符
环境准备
首先创建一个测试文件:
[furongwang@shell ~]$ vim words
cat
category
acat
concatenate
dog
普通字符匹配
最简单的正则表达式就是普通字符本身:
[furongwang@shell ~]$ cat words | grep 'cat'
cat
category
acat
concatenate
字符集匹配
[...]
- 匹配任意一个字符
[furongwang@shell ~]$ echo cbt >> words
[furongwang@shell ~]$ echo c1t >> words
[furongwang@shell ~]$ cat words | grep 'c[ab]t'
cat
cbt
范围匹配
[a-z]
:匹配所有小写字母[A-Z]
:匹配所有大写字母[0-9]
:匹配所有数字
[furongwang@shell ~]$ cat words | grep 'c[a-z]t'
cat
cbt[furongwang@shell ~]$ echo cCt >> words
[furongwang@shell ~]$ cat words | grep 'c[A-Z]t'
cCt[furongwang@shell ~]$ cat words | grep 'c[0-9]t'
c1t
[^...]
- 排除字符
[furongwang@shell ~]$ cat words | grep 'c[^ab]t'
c1t# ^放中间会被当做普通字符
[furongwang@shell ~]$ echo c^t >> words
[furongwang@shell ~]$ cat words | grep 'c[a^b]t'
cat
category
acat
concatenate
cbt
c^t
.
- 匹配任意单个字符
[furongwang@shell ~]$ cat words | grep 'c.t'
cat
category
acat
concatenate
cbt
c1t
cCt
c.t
c^t
\
- 转义字符
[furongwang@shell ~]$ echo c.t >> words
[furongwang@shell ~]$ cat words | grep 'c\.t'
c.t
|
- 或操作(扩展正则表达式)
[furongwang@shell ~]$ cat words | egrep 'cat|dog'
# 或者
[furongwang@shell ~]$ cat words | grep -E 'cat|dog'
cat
category
acat
concatenate
dog
字符类
字符类 | 描述 | 等价形式 |
---|---|---|
[[:digit:]] | 数字 | [0-9] |
[[:xdigit:]] | 十六进制数字 | [0-9a-fA-F] |
[[:lower:]] | 小写字母 | [a-z] |
[[:upper:]] | 大写字母 | [A-Z] |
[[:alpha:]] | 字母字符 | [A-Za-z] |
[[:alnum:]] | 字母数字字符 | [0-9A-Za-z] |
[[:blank:]] | 空白字符(空格、制表符等) | |
[[:space:]] | 空白字符 | |
[[:punct:]] | 标点符号 | |
[[:print:]] | 可打印字符 | |
[[:graph:]] | 可打印字符(不包括空格) | |
[[:cntrl:]] | 控制字符 |
非打印字符
字符 | 描述 |
---|---|
\c | 匹配控制字符 |
\f | 匹配换页符 |
\n | 匹配换行符 |
\r | 匹配回车符 |
\s | 匹配任何空白字符 |
\S | 匹配任何非空白字符 |
\w | 匹配字母、数字、下划线 |
\W | 匹配任何非单词字符 |
\t | 匹配制表符 |
\v | 匹配垂直制表符 |
grep命令支持
\w
、\W
、\s
、\S
定位符
^
- 匹配行首
[furongwang@shell ~]$ cat words | grep '^cat'
cat
category
$
- 匹配行末
[furongwang@shell ~]$ cat words | grep 'cat$'
cat
acat
\b
- 单词边界
[furongwang@shell ~]$ echo hello cat >> words
[furongwang@shell ~]$ cat words | grep '\bcat'
cat
category
hello cat
\B
- 非单词边界
[furongwang@shell ~]$ cat words | grep '\Bcat'
acat
concatenate
\<
和 \>
- 单词边界
# \< 匹配单词左边界
[furongwang@shell ~]$ cat words | grep '\<cat'
cat
category
hello cat# \> 匹配单词右边界
[furongwang@shell ~]$ cat words | grep 'cat\>'
cat
acat
hello cat
次数限定
*
- 匹配0次或多次
[furongwang@shell ~]$ echo dg >> words
[furongwang@shell ~]$ echo doog >> words
[furongwang@shell ~]$ cat words | grep 'do*g'
dog
dg
doog
+
- 匹配1次或多次(扩展正则表达式)
[furongwang@shell ~]$ cat words | egrep 'do+g'
dog
doog
?
- 匹配0次或1次(扩展正则表达式)
[furongwang@shell ~]$ cat words | egrep 'do?g'
dog
dg
{n}
- 匹配n次(扩展正则表达式)
[furongwang@shell ~]$ cat words | egrep 'do{2}g'
doog
{m,n}
- 匹配m到n次(扩展正则表达式)
[furongwang@shell ~]$ echo dooog >> words
[furongwang@shell ~]$ echo doooog >> words [furongwang@shell ~]$ cat words | egrep 'do{2,3}g'
doog
dooog
{m,}
- 匹配至少m次(扩展正则表达式)
[furongwang@shell ~]$ cat words | egrep 'do{2,}g'
doog
dooog
doooog
{,n}
- 匹配最多n次(扩展正则表达式)
[furongwang@shell ~]$ cat words | egrep 'do{,3}g'
dog
doog
dg
dooog
()
- 子表达式(扩展正则表达式)
[furongwang@shell ~]$ echo dogdog >> words
[furongwang@shell ~]$ echo dogdogdog >> words
[furongwang@shell ~]$ echo dogdogdogdog >> words # 匹配包含重复了2-3次()中内容的行
[furongwang@shell ~]$ cat words | egrep '(dog){2,3}'
dogdog
dogdogdog
dogdogdogdog
反向引用
对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式。
每个缓冲区都可以使用 \N
访问,其中 N
为一个标识特定缓冲区的一位或两位十进制数。
\N
这用引用方式称之为反向引用。
反向引用允许你引用前面捕获的子表达式:
[furongwang@shell ~]$ echo 'furongwang litangwang otto furongwang litangwang otto' | \
> egrep -o '(furongwang) (litangwang).*\1'# 输出结果
furongwang litangwang otto furongwang[furongwang@shell ~]$ echo 'Is is the cost of of gasoline going up up?' | \
> egrep -o '\b([a-z]+) \1\b'
# 正则表达式解释:
# \b : 单词边界,确保匹配的是完整单词
# ([a-z]+) : 捕获组1,匹配一个或多个小写字母(一个单词)
# \s+ : 匹配一个或多个空白字符(空格、制表符等)
# \1 : 反向引用,匹配与第一个捕获组完全相同的内容(即至少重复出现了一次的内容)
# \b : 单词边界,确保匹配的是完整单词
# 输出结果
of of
up up
实战练习:过滤有效IPv4地址
给定以下文件内容:
0.0.0.0
1.1.1.1
11.11.11.111
111.111.111.111
999.9.9.9
01.1.1.1
10.0.0.0
0.1.1.1
266.1.1.1
248.1.1.1
256.1.1.1
过滤出所有有效IPv4地址的正则表达式:
\b(([1-9][0-9]?)|(1[0-9]{2})|(2[0-4][0-9])|(25[0-5]))(\.(([0-9])|([1-9][0-9])|(1[0-9]{2})|(2[0-4][0-9])|(25[0-5]))){3}\b
或者更简洁的版本:
'\b([1-9][0-9]?|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){2}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\b'