[Shell编程] Shell的正则表达式
目录
一、什么是正则表达式?
二、为什么要学正则表达式?
三、正则表达式基础:元字符与核心规则
1️⃣基础元字符汇总
2️⃣实操练习:用 grep 命令体验基础规则
(1)查找特定字符 / 字符串
(2)用[]匹配候选字符
(3)用[^]反向选择
(4)行首^与行尾$
(5)任意字符.与重复*
(6)连续次数{n,m
四、正则表达式进阶:扩展元字符与工具
1️⃣扩展元字符汇总
2️⃣扩展正则实操示例
(1)+:至少 1 次重复
(2)|:多模式匹配
(3)()与反向引用:匹配重复字符
五、初学者学习建议
一、什么是正则表达式?
简单来说,正则表达式(Regular Expression,简称 regex、regexp 或 RE) 是用单个字符串来描述、匹配一系列符合特定规则的字符串的工具。它就像一把 "文本过滤器",能快速从大量文本中找到符合规则的内容,实现查找、替换、提取等操作。
举个例子:如果想验证一个字符串是不是数字(0 或非 0 开头的数字),用正则表达式可以写成^0$|^[1-9][0-9]*$
;验证一个字符串是否全是汉字,可用^[\u4e00-\u9fa5]{0,}$
。
二、为什么要学正则表达式?
正则表达式的核心价值在于高效处理文本,主要作用有 3 点:
- 数据验证:检查文本是否符合特定模式(如手机号、邮箱、身份证号格式);
- 文本替换:批量修改文档中符合规则的内容(如替换所有错误的拼写);
- 子串提取:从复杂文本中提取关键信息(如从日志中提取所有错误代码)。
它的应用场景非常广泛:在 Linux/Unix 系统中(如 grep、sed 命令)、编程语言中(Java、Python、JavaScript 等)、甚至日常办公软件(如 Excel 高级查找)中都能用到。对于系统管理员来说,正则表达式更是处理日志、定位问题的 "利器"—— 能从成千上万行日志中快速揪出 "登录失败"" 服务崩溃 " 等关键信息。
三、正则表达式基础:元字符与核心规则
正则表达式由普通字符(如 a-z、0-9)和元字符(具有特殊含义的字符)组成。元字符是正则的核心,我们先从基础元字符学起。
1️⃣基础元字符汇总
元字符 | 含义 | 示例 |
---|---|---|
^ | 匹配行首(字符串开始位置) | ^the 匹配以 "the" 开头的行 |
$ | 匹配行尾(字符串结束位置) | end$ 匹配以 "end" 结尾的行;^$ 匹配空行 |
. | 匹配除换行符(\n)外的任意一个字符 | g..d 匹配 "good"(g + 两个字符 + d)、"god"(g + 一个字符 + d,注意:. 可以是任意字符) |
* | 匹配前面的子表达式 0 次或多次 | oo* 匹配 "o"(0 次 o)、"oo"(1 次 o)、"ooo"(2 次 o)等 |
[] | 匹配字符集中的任意一个字符 | [0-9] 匹配任意数字;sh[io]rt 匹配 "short"(sh+o+rt)或 "shirt"(sh+i+rt) |
[^] | 匹配不在字符集中的任意一个字符 | [^0-9] 匹配非数字字符;[^a-z]oo 匹配 "oo" 前不是小写字母的内容 |
\ | 转义字符,取消特殊符号的含义 | \! 匹配感叹号(! 原本可能有特殊含义);\$ 匹配美元符号 |
{n} | 匹配前面的子表达式 n 次(需加 \ 转义,egrep/awk 除外) | o\{2\} 匹配连续 2 个 o;[0-9]\{2\} 匹配 2 位数字 |
{n,} | 匹配前面的子表达式至少 n 次 | o\{2,\} 匹配至少 2 个 o |
{n,m} | 匹配前面的子表达式 n 到 m 次 | o\{2,3\} 匹配 2-3 个 o |
\w | 匹配字母、数字或下划线(等价于[A-Za-z0-9_] ) | \w+ 匹配一个单词(如 "hello"、"user123") |
\d | 匹配数字(等价于[0-9] ) | \d{3} 匹配 3 位数字 |
\s | 匹配空白字符(空格、制表符、换行符等) | a\sb 匹配 "a b"(a + 空格 + b) |
2️⃣实操练习:用 grep 命令体验基础规则
我们先准备一个测试文件test.txt
(内容如下),后续例子都基于这个文件操作:
plaintext
1: he was short and fat. He was wearing a blue polo shirt with black pants.
2: The home of Football on BBC Sport online.
3: the tongue is boneless but it breaks bones.12!
4: google is the best tools for search keyword.
5:
6: The year ahead will test our political establishment to the limit.
7: PI=3.141592653589793238462643383249901429
8: a wood cross!
9: Actions speak louder than words
10: #woood #
11: #woooooood #
12: AxyzxyzxyzxyzC
13: I bet this place is really spooky late at night!
14: Misfortunes never come alone/single.
15: I shouldn't have lett so tast.
(1)查找特定字符 / 字符串
用grep
命令查找,-n
显示行号,-i
忽略大小写:
bash
# 查找包含"the"的行(区分大小写)
grep -n 'the' test.txt
# 结果:行3、4、6(包含"the")# 查找包含"the"的行(不区分大小写)
grep -in 'the' test.txt
# 结果:行2(The)、3(the)、4(the)、6(the)
(2)用[]
匹配候选字符
[]
表示 "任选其一",比如查找 "short" 和 "shirt"(都包含 "sh" 和 "rt",中间是 i 或 o):
bash
grep -n 'sh[io]rt' test.txt
# 结果:行1(short)、行2(shirt)
查找包含数字的行:
bash
grep -n '[0-9]' test.txt
# 结果:行3(12!)、行7(3.1415...)
(3)用[^]
反向选择
[^字符集]
表示 "不匹配字符集中的内容"。比如查找 "oo" 前面不是 "w" 的字符串:
bash
grep -n '[^w]oo' test.txt
# 解释:排除"woo",匹配"foo"(行2)、"goo"(行4)等
(4)行首^
与行尾$
- 查找以 "the" 开头的行:
bash
grep -n '^the' test.txt # 结果:行3(the tongue...)
- 查找以 "s" 结尾的行:
bash
grep -n 's$' test.txt # 结果:行9(words)
- 查找空行(行首到行尾没有内容):
bash
grep -n '^$' test.txt # 结果:行5
(5)任意字符.
与重复*
-
.
匹配任意一个字符,比如查找 "w 开头、d 结尾,中间有 2 个任意字符" 的字符串(共 4 个字符):bash
grep -n 'w..d' test.txt # 匹配"wood"(行8:w+oo+d)
-
*
匹配前面的字符 0 次或多次,比如查找 "w 开头、d 结尾,中间至少有 1 个 o" 的字符串:bash
grep -n 'woo*d' test.txt # 匹配"wood"(1个o)、"woood"(2个o)等
(6)连续次数{n,m}
指定字符重复的次数,比如查找 "w 开头、d 结尾,中间有 2-5 个 o" 的字符串:
bash
grep -n 'wo\{2,5\}d' test.txt # 匹配"woood"(3个o),不匹配"wood"(1个o)或"woooooood"(7个o)
四、正则表达式进阶:扩展元字符与工具
基础正则能满足大部分需求,但复杂场景需要扩展正则表达式(POSIX 扩展语法)。扩展元字符不需要转义符\
,支持的工具包括egrep
(grep -E
)、awk
、sed -r
等。
1️⃣扩展元字符汇总
元字符 | 含义 | 示例 | ||
---|---|---|---|---|
+ | 匹配前面的子表达式 1 次及以上(至少 1 次) | go+d 匹配 "god"(1 个 o)、"good"(2 个 o)等 | ||
? | 匹配前面的子表达式 0 次或 1 次 | go?d 匹配 "gd"(0 个 o)或 "god"(1 个 o) | ||
() | 将括号内的内容作为一个整体 | g(oo)+d 匹配 "good"(oo1 次)、"gooood"(oo2 次)等 | ||
` | ` | 表示 "或",匹配多个模式中的一个 | `g(oo | la) d`匹配"good"或"glad" |
2️⃣扩展正则实操示例
(1)+
:至少 1 次重复
查找包含 "ll" 及以上(至少 2 个 l)的行:
bash
egrep -n 'll+' test.txt # 匹配"Football"(ll)、"really"(ll)等
(2)|
:多模式匹配
查找包含 "test" 或 "than" 的行:
bash
egrep -n 'test|than' test.txt # 匹配行6(test)、行9(than)
(3)()
与反向引用:匹配重复字符
()
用于定义 "捕获组"(暂存匹配的字符),\1
引用第一个捕获组的内容。比如查找包含 "连续 2 个相同字符" 的行:
bash
egrep -n '(.)\1' test.txt # 匹配"Football"(ll)、"spooky"(oo)等
解释:(.)
捕获任意字符(如 l),\1
匹配和它相同的字符(另一个 l),合起来就是 "ll"。
五、初学者学习建议
- 从基础元字符开始:先掌握
^
、$
、.
、*
、[]
,用grep
多练习; - 结合实例理解:对着
test.txt
敲命令,观察输出结果,比死记规则更有效; - 逐步过渡到扩展正则:熟练基础后,再学
+
、?
、()
,用egrep
实践; - 善用工具测试:遇到复杂规则,可先用在线正则测试工具(如 regex101)验证,再到终端执行。