正则表达式详解:从基础到扩展的全面指南
正则表达式详解:从基础到扩展
正则表达式(Regular Expression,简称 RE)是用于描述字符匹配模式的语法规则,广泛应用于 Linux 文本处理工具(如 grep
、sed
、awk
)中,实现文本过滤、查找、替换等自动化操作。本文从概念、基础正则、扩展正则到特殊字符组,结合实例系统讲解正则表达式的用法。
一、正则表达式概述
1. 核心概念
正则表达式是一套“模式模板”,通过“普通字符”(如字母、数字)和“元字符”(如 ^
、$
、*
)的组合,定义文本的匹配规则。Linux 工具(如 grep
)会根据该规则过滤数据:
- 匹配的数据:符合模式规则,被保留并进一步处理;
- 滤掉的数据:不符合模式规则,被排除。
2. 作用与目的
核心作用 | 具体目的 |
---|---|
格式校验 | 判断字符串是否符合特定格式(如手机号、邮箱、IP 地址)。 |
文本过滤 | 从大量文本中提取符合模式的内容(如从日志中筛选错误信息)。 |
内容替换 | 批量替换文本中符合模式的内容(如 sed 替换所有手机号的中间4位为 **** )。 |
二、基础正则表达式(BRE)
基础正则是正则的核心子集,支持 grep
、sed
(默认模式)、awk
等工具,核心元字符及用法如下:
1. 核心元字符表
元字符 | 含义与功能 | 示例 | 匹配结果(以文本“lok、look、loook、loooooak”为例) |
---|---|---|---|
\ | 转义字符:取消后续元字符的特殊含义(如 \$ 匹配字面量 $ ,而非行尾)。 | grep "lo\$" a.txt | 匹配以“lo”结尾的行(如“alo”)。 |
^ | 行首锚定:匹配字符串/行的开始位置。 | grep "^lo" a.txt | 匹配以“lo”开头的行(如“lok、look”)。 |
$ | 行尾锚定:匹配字符串/行的结束位置。 | grep "k$" a.txt | 匹配以“k”结尾的行(如“lok、look”)。 |
^$ | 匹配空行(行首到行尾无任何字符,包括空格)。 | grep "^$" b.txt | 提取文件 b.txt 中的所有空行。 |
. | 匹配除换行符(\n )外的任意一个字符。 | grep "lo.k" a.txt | 匹配“lo”后接1个任意字符、再接“k”(如“look”)。 |
* | 匹配前面一个字符0次或多次(可理解为“可有可无,多了也可以”)。 | grep "lo*k" a.txt | 匹配“l”后接0个或多个“o”、再接“k”(如“lk、lok”)。 |
[list] | 匹配 list 列表中的任意一个字符(list 可是字符、范围,如 a-z )。 | grep "lo[ao]k" a.txt | 匹配“lo”后接“a”或“o”、再接“k”(如“look、loak”)。 |
[^list] | 匹配不在 list 列表中的任意一个字符(取反)。 | grep "lo[^0-9]k" a.txt | 匹配“lo”后接非数字字符、再接“k”(如“look”)。 |
\{n\} | 匹配前面一个字符恰好 n 次(grep 需加 \ ,egrep 可省略)。 | grep "lo\{2\}k" a.txt | 匹配“lo”后接2个“o”、再接“k”(仅“look”)。 |
\{n,\} | 匹配前面一个字符至少 n 次。 | grep "lo\{3,\}k" a.txt | 匹配“lo”后接3个及以上“o”、再接“k”(如“loook”)。 |
\{n,m\} | 匹配前面一个字符n 到 m 次(含 n 和 m)。 | grep "lo\{2,4\}k" a.txt | 匹配“lo”后接2-4个“o”、再接“k”(如“look、loook”)。 |
2. 实战示例
以文件 a.txt
为例(内容如下),演示基础正则的用法:
#创建a.txt
[root@ansible ~]# vim a.txtlk
lok
look
loook
loooooak
ooooloooook
abbbbcd
示例 1:匹配以“lo”开头、以“k”结尾的行
grep "^lo.*k$" a.txt # .* 匹配任意字符(0次或多次)
[root@ansible ~]# grep "^lo.*k$" a.txt
lok
look
loook
loooooak#注意:^lo 匹配行首的“lo”,此行使“ooool”中的“lo”非行首,不匹配ooooloooook
示例 2:匹配“lo”后接2-3个“o”、再接“k”的行
[root@ansible ~]# grep "lo\{2,3\}k" a.txt
look
loook
示例 3:匹配包含非字母字符的行
[root@ansible ~]# grep "[^a-zA-Z]" a.txt # [^a-zA-Z] 匹配非字母字符
# 输出:(若文件无数字/符号,此例无输出;若有“lo12k”,则会匹配)
三、扩展正则表达式(ERE)
扩展正则在基础正则的基础上增加了更多元字符(如 +
、?
、()
、|
),简化了复杂模式的编写,需用 egrep
(或 grep -E
)、awk
、sed -r
等工具支持。
1. 核心元字符表(新增/优化)
元字符 | 含义与功能 | 示例 | 匹配结果(基于 a.txt ) |
---|---|---|---|
+ | 匹配前面一个字符1次或多次(比 * 严格,至少1次)。 | egrep "lo+k" a.txt | 匹配“lo”后接1个及以上“o”、再接“k”(如“lok、look”),不匹配“lk”。 |
? | 匹配前面一个字符0次或1次(最多1次)。 | egrep "lo?k" a.txt | 匹配“lo”后接0个或1个“o”、再接“k”(如“lk、lok”),不匹配“look”。 |
() | 分组:将括号内的字符视为一个整体,用于批量匹配或结合 + /? /` | `。 | egrep "l(oo)+k" a.txt |
` | ` | 逻辑“或”:匹配 ` | ` 两侧的任意一个模式。 |
{n} /{n,} /{n,m} | 与基础正则 \{n\} 功能一致,但无需加 \ (简化写法)。 | egrep "lo{3}k" a.txt | 匹配“lo”后接3个“o”、再接“k”(仅“loook”)。 |
2. 实战示例
示例 1:匹配“lo”后接1个及以上“o”、再接“k”的行
[root@ansible ~]# egrep "lo+k" a.txt # + 要求至少1个o
lok
look
loook
ooooloooook
示例 2:匹配“lk”或“lok”(最多1个o)
[root@ansible ~]# egrep "lo?k" a.txt # ? 允许0个或1个o
lk # (0个o)
lok # lok(1个o)
示例 3:匹配“look”或“labk”(分组+或)
# 先向 a.txt 追加“labk”
[root@ansible ~]# echo "labk" >> a.txt
# 匹配“l(oo|ab)k”
[root@ansible ~]# egrep "l(oo|ab)k" a.txt
look #(oo组)
labk #(ab组)
四、特殊字符组(字符类)
为简化常用字符范围的编写,正则提供了预定义的“特殊字符组”(也称字符类),适用于基础和扩展正则,格式为 [[:字符组名:]]
。
1. 常用特殊字符组表
字符组 | 含义与等价范围 | 用途示例 |
---|---|---|
[[:alpha:]] | 任意字母(大写+小写),等价于 [a-zA-Z] | 匹配用户名中的字母:grep "[[:alpha:]]+" a.txt |
[[:alnum:]] | 任意字母或数字,等价于 [a-zA-Z0-9] | 匹配密码中的字母数字:grep "[[:alnum:]]{6,}" a.txt |
[[:digit:]] | 任意数字,等价于 [0-9] | 匹配手机号中的数字:grep "[[:digit:]]{11}" log.txt |
[[:lower:]] | 任意小写字母,等价于 [a-z] | 匹配小写单词:grep "^[[:lower:]]+" a.txt |
[[:upper:]] | 任意大写字母,等价于 [A-Z] | 匹配大写开头的句子:grep "^[[:upper:]]" a.txt |
[[:space:]] | 任意空白字符(空格、Tab、换行等),等价于 [ \t\n] | 匹配含空格的行:grep "[[:space:]]" a.txt |
[[:punct:]] | 任意标点符号(如 ! 、@ 、# 、. 等) | 匹配含标点的行:grep "[[:punct:]]" a.txt |
五、基础与扩展正则的核心区别
维度 | 基础正则(BRE) | 扩展正则(ERE) |
---|---|---|
支持工具 | grep 、sed (默认)、awk | egrep (grep -E )、sed -r 、awk |
元字符差异 | {n} /{n,} /{n,m} 需加 \ (即 \{n\} ) | {n} /{n,} /{n,m} 无需加 \ |
新增元字符 | 无 + 、? 、() 、` | ` |
适用场景 | 简单匹配(如行首行尾、固定次数) | 复杂匹配(如分组、或逻辑、至少1次) |
总结
正则表达式是 Linux 文本处理的“瑞士军刀”,核心要点:
- 基础正则:掌握
^
、$
、.*
、[list]
、\{n,m\}
,满足日常简单过滤需求; - 扩展正则:用
+
、?
、()
、|
简化复杂模式,需配合egrep
或grep -E
; - 特殊字符组:用
[[:digit:]]
、[[:alpha:]]
等简化字符范围编写; - 工具适配:根据需求选择工具(简单用
grep
,复杂用egrep
/sed -r
)。
通过多练习(如匹配日志、校验格式、批量替换),可逐步熟练正则表达式的灵活应用,大幅提升文本处理效率。