一、什么是正则表达式

正则表达式是一种文本匹配规则,用于在文本中查找、筛选或验证符合某种模式的内容。

在 Linux 日常运维里,正则最常出现的地方包括:

  • grep 过滤文本
  • sed 替换文本
  • awk 条件筛选
  • Shell 脚本中的模式判断

原始笔记中还提到一个正则可视化工具:

正则图形化显示工具

二、正则和通配符有什么区别

类型 匹配对象 常见场景
正则表达式 匹配文件内容、文本行、字符串模式 grepsedawk、开发语言
通配符 匹配文件名或命令参数展开 Shell 命令行、文件匹配

简单理解:

  • 通配符更多在命令执行前由 Shell 展开
  • 正则更多在命令运行时用于匹配文本内容

三、正则的常见分类

分类 常见符号
基础正则 BRE ^ $ ^$ . \ * .* [] [^]
扩展正则 ERE + | () {} ?
Perl 风格正则 \d \s \w \D \S \W

四、基础正则 BRE

4.1 常见符号含义

符号 含义
^ 以某内容开头
$ 以某内容结尾
^$ 空行
. 任意单个字符,不包含换行
\ 转义字符
* 前一个字符出现 0 次或多次
.* 任意多个任意字符
[] 匹配方括号中的任意一个字符
[^] 取反匹配

4.2 常见示例

匹配以 l 开头的行:

$ grep '^l' a.txt
love
linux

匹配以 x 结尾的行:

$ grep 'x$' a.txt
linux

找空行并显示行号:

$ grep -n '^$' a.txt

排除空行:

$ grep -vn '^$' a.txt

排除空行后再排除注释行:

$ grep -v '^$' /etc/ssh/sshd_config | grep -v '^#'

匹配任意非空字符:

$ grep '.' a.txt

匹配以点号结尾的行,注意点号要转义:

$ grep '\.$' a.txt

匹配任意小写字母:

$ grep '[a-z]' a.txt

匹配任意大写字母:

$ grep '[A-Z]' a.txt

匹配任意数字:

$ grep '[0-9]' a.txt

五、扩展正则 ERE

扩展正则通常配合下面命令使用:

$ egrep 'pattern' file
$ grep -E 'pattern' file

如果使用普通 grep,则需要对某些符号额外转义。

5.1 常见符号含义

符号 含义
+ 前一个字符出现 1 次或多次
|
() 分组
{n,m} 前一个字符出现 n 到 m 次
{n} 前一个字符恰好出现 n 次
{n,} 前一个字符至少出现 n 次
? 前一个字符出现 0 次或 1 次

5.2 常见示例

匹配连续出现的 0

$ egrep '0+' a.txt

匹配连续数字:

$ egrep '[0-9]+' a.txt

匹配包含 aaalinux 的行:

$ egrep 'aaa|linux' a.txt

过滤 /etc/services 中包含 sshhttpsmtp 的行:

$ egrep 'ssh|http|smtp' /etc/services

排除空行或注释行,并显示行号:

$ egrep -vn '^$|^#' /etc/ssh/sshd_config

用分组精确匹配包名开头:

$ rpm -qa | egrep '^(tree|vim|sl)'

匹配连续出现 4 次的 0

$ egrep '0{4}' a.txt

匹配至少连续出现 4 次的 0

$ egrep '0{4,}' a.txt

身份证号匹配示例:

$ egrep '[0-9]{17}[0-9X]$' id.txt

匹配 l 可以有也可以没有,再跟上 o

$ egrep 'l?o' a.txt

六、Perl 风格正则

这类正则常见于 grep -P、Perl、部分脚本语言与高级文本处理工具中。

6.1 常见符号含义

符号 含义
\d 数字,等价于 [0-9]
\s 空白字符
\w 单词字符,等价于 [0-9a-zA-Z_]
\D 非数字
\S 非空白字符
\W 非单词字符

6.2 示例

匹配包含数字的行:

$ grep -P '\d' a.txt

七、小结

正则表达式最容易学乱的地方,不是符号太多,而是没有分层理解。建议按下面顺序掌握:

1、先掌握基础正则:^$.*[] 2、再学扩展正则:+|(){}? 3、最后再接触 \d\w 这类 Perl 风格写法

把这套顺序走通后,grep、sed、awk 的大部分文本匹配场景都会容易很多。