当前位置: 首页 > news >正文

十二、Linux Shell脚本:正则表达式

作者:IvanCodes
日期:2025年8月11日
专栏:Linux教程

正则表达式的本质是一套用于描述和匹配字符串集合规则模式语言 它通过组合普通字符和具有特殊含义元字符定义一个“模板”,然后用这个模板去文本中进行模式匹配

一、基本匹配 (字面量匹配)

最基础的正则表达式就是字符串本身,它会精确匹配文本中完全相同的字符序列。

代码示例 (使用 grep 命令演示):

# 在字符串中查找 "cat"
echo "My cat is black, your cat is white." | grep --color=always 'cat'

(--color=always 用于高亮匹配部分。为防止Shell对特殊字符进行解释,强烈建议将正则表达式用单引号 '' 包裹。)

二、核心元字符

正则表达式的威力来源于元字符,这些字符不再代表字面含义,而是被赋予了特殊的匹配功能

1.. (点) - 匹配任意单个字符

一个点 . 可以代表除换行符外任何一个字符。

# 匹配 "c" 和 "t" 之间有任意一个字符的模式
echo "cat cot c-t c@t chart" | grep --color=always 'c.t'
# 将匹配 cat, cot, c-t, c@t

2.* (星号) - 匹配前一个元素零次或多次

星号 * 表示其紧邻的前一个字符或分组可以出现任意次数 (0, 1, 2, …)。

# 匹配 "go" 和 "gle" 之间有任意数量 "o" 的模式
echo "ggle google goooogle gogle" | grep --color=always 'go*gle'
# 将匹配 ggle (o出现0次), google, goooogle

3.+ (加号) - 匹配前一个元素一次或多次

加号 + 与星号类似,但要求其前一个元素至少出现一次 (1, 2, 3, …)。

# 匹配 "go" 和 "gle" 之间至少有一个 "o" 的模式
echo "ggle google goooogle gogle" | grep -E --color=always 'go+gle'
# 将匹配 google, goooogle,但不匹配 ggle

注意 - 正则表达式方言 (Flavor):
+, ?, |, () 等元字符,在基础正则表达式 (BRE) 中 (如标准 grep) 需要前置反斜杠 \ (如 \+) 才能生效。而在扩展正则表达式 (ERE) 中 (如 grep -Eegrep) 则直接使用。为方便和现代,本教程的示例主要使用 ERE

4.? (问号) - 匹配前一个元素零次或一次

问号 ? 表示其前一个元素是可选的

# 匹配 "color" 和 "colour"
echo "color colour counselor" | grep -E --color=always 'colou?r'

5.^ (尖角号) - 匹配行首

^ 位于正则表达式的开头时,它锚定匹配必须从一行的开始处发生。

# 匹配以 "start" 开头的行
echo -e "start of the line\nmiddle start end" | grep -E --color=always '^start'
# 只会匹配第一行

6.$ (美元符) - 匹配行尾

$ 位于正则表达式的末尾时,它锚定匹配必须在一行的结束处结束。

# 匹配以 "end" 结尾的行
echo -e "the line must end\nend of the line" | grep -E --color=always 'end$'
# 只会匹配第一行

组合使用 ^$ 可以进行整行匹配。例如 ^root$ 只匹配内容仅为 “root” 的行。

7.[...] (方括号) - 匹配字符集合

方括号 [...] 定义了一个字符集,它会匹配集合内任意一个字符。

[abc]: 匹配 ‘a’, ‘b’, ‘c’ 中的一个
[0-9]: 匹配任意一个数字。
[a-z]: 匹配任意一个小写字母。
[a-zA-Z]: 匹配任意一个字母。
[^abc]: (当^在方括号内开头时) 反向匹配,匹配除 ‘a’, ‘b’, ‘c’ 之外的任意一个字符。

# 匹配 "log" 后跟任意一个数字,然后是 ".txt"
echo "log1.txt logA.txt log-3.txt" | grep -E --color=always 'log[0-9]\.txt'
# 将匹配 log1.txt

8.\ (反斜杠) - 转义元字符

反斜杠 \ 用于去除其后元字符的特殊含义,使其变回字面字符。例如,要匹配一个真正的点 .,必须写成 \.

三、量词与分组

1. 精确量词 {}

花括号 {} 用于精确控制前一个元素重复次数

  • {n}: 正好 n 次。
  • {n,}: 至少 n 次。
  • {n,m}: n 到 m 次 (包含n和m)。
# 匹配一个4位数的年份
echo "Date: 2024, Item: 123" | grep -E --color=always '[0-9]{4}'
# 将匹配 2024

2. 分组 () 与或 |

  • 圆括号 (): 将多个字符组合成一个逻辑单元,可以对整个单元应用量词。默认情况下,() 还会捕获其匹配到的内容,用于后续引用
  • 竖线 |: 表示“或”关系,匹配其左边或右边的表达式。
# 匹配 "file.log" 或 "file.txt"
echo "file.log file.txt file.dat" | grep -E --color=always 'file\.(log|txt)'# 匹配 "http://" 或 "https://", 后跟任意字符
echo "URL: https://example.com" | grep -E --color=always '(http|https)://.*'

四、常见应用场景与工具

正则表达式在Linux命令行中无处不在

  • grep: 文本搜索
  • sed: 流编辑器,用于文本替换和转换。
  • awk: 强大的文本处理语言。
  • find: -regex 选项支持基于路径的正则匹配
  • 文本编辑器: vim, emacs 等都内置了强大的正则搜索/替换功能。
  • 编程语言: Python (re), Perl, JavaScript (RegExp), Java (java.util.regex) 等几乎所有语言都提供了正则库。

五、更多信息

  • POSIX 字符类: 为了更好的可移植性对非ASCII字符的支持,可以使用 [[:...:]] 形式的字符类,例如 [[:digit:]] 等同于 [0-9][[:alpha:]] 等同于 [a-zA-Z]
  • 贪婪与非贪婪匹配: 默认情况下,像 *+ 这样的量词是贪婪的,即它们会尽可能多地匹配字符。在支持PCRE (Perl Compatible Regular Expressions) 的引擎中 (如 grep -P),可以在量词后添加 ? (如 *?, +?) 来切换到非贪婪模式,即尽可能少地匹配。

总结: 正则表达式是处理和分析文本数据的基石。从简单的字面量匹配,到组合使用元字符、量词、分组和锚点,可以构建出极其精确和灵活匹配模式。熟练掌握正则表达式极大地提升你在命令行脚本编程中的工作效率


练习题

题目一:基本匹配与元字符
写一个正则表达式,匹配包含 colorcolour 这两个单词的行。

题目二:数字匹配
写一个正则表达式,匹配一个三位数的整数。

题目三:开头与结尾
写一个正则表达式,匹配以大写字母开头,并且以句号 . 结尾的整行。

题目四:字符集合
写一个正则表达式,匹配一个小写元音字母 (a, e, i, o, u)。

题目五:量词
写一个正则表达式,匹配一个由至少两个数字组成的字符串。

题目六:转义
写一个正则表达式来精确匹配字符串 127.0.0.1

题目七:分组与或
写一个正则表达式,匹配 apple.jpgapple.png

题目八:综合应用 (简单邮箱格式)
写一个非常简化的正则表达式,尝试匹配类似 user@example.com 格式的字符串(假设用户名和域名只包含字母、数字、下划线,并且域名只有两部分)。

题目九:反向匹配
写一个正则表达式,匹配不包含任何数字的行。

题目十:POSIX字符类
使用POSIX字符类,写一个正则表达式,匹配一个或多个十六进制字符 (0-9, a-f, A-F)。

答案与解析

答案一:

colou?r
  • 解析: ? 量词表示其前一个字符 (u) 可以出现0次或1次,因此可以同时匹配 colorcolour

答案二:

[0-9]{3}
  • 解析: [0-9] 匹配任意一个数字{3} 这个量词表示前面的元素必须正好出现3次。如果要求整行就是三位数,应写成 ^[0-9]{3}$

答案三:

^[A-Z].*\.$
  • 解析: ^ 匹配行首[A-Z] 匹配一个大写字母.* 匹配任意数量的任意字符,\. 匹配一个字面上的点$ 匹配行尾

答案四:

[aeiou]
  • 解析: [...] 字符集会匹配其中列出任意一个字符。

答案五:

[0-9]{2,}
  • 解析: {2,} 量词表示前面的元素 ([0-9]) 必须出现至少2次

答案六:

127\.0\.0\.1
  • 解析: IP地址中的.元字符,必须使用反斜杠 \ 进行转义,才能匹配其字面含义

答案七:

apple\.(jpg|png)
  • 解析: \. 匹配(jpg|png) 使用分组 ()| 来匹配 jpgpng 字符串。

答案八:

[a-zA-Z0-9_]+@[a-zA-Z0-9_]+\.[a-zA-Z0-9_]+
  • 解析: [a-zA-Z0-9_]+ 匹配至少一个字母、数字或下划线,用于匹配用户名域名部分@\. 匹配字面符号。这是一个简化模型

答案九:

^[^0-9]*$
  • 解析: ^$ 锚定整行[^0-9] 是一个反向字符集,匹配任何非数字字符。* 表示这些非数字字符可以出现任意次数 (包括0次,以匹配空行)。

答案十:

[[:xdigit:]]+
  • 解析: [[:xdigit:]]POSIX字符类,专门用于匹配十六进制字符 (等效于 [0-9a-fA-F])。+ 表示匹配一次或多次。使用POSIX字符类可读性更好兼容性更强
http://www.dtcms.com/a/325840.html

相关文章:

  • Linux线程——线程控制及理解
  • SDRAM详细分析——01 SDRAM基础
  • MySQL 函数
  • 【PyTorch学习笔记 - 01】 Tensors(张量)
  • STM32 HAL库驱动W25QXX Flash
  • es基本概念-自学笔记
  • 嵌入式硬件中MOS管图形详解
  • Unity笔记(五)知识补充——场景切换、退出游戏、鼠标隐藏锁定、随机数、委托
  • Mini-Omni: Language Models Can Hear, Talk While Thinking in Streaming
  • 数据库的基本操作(约束与DQL查询)
  • 分治-归并-912.排序数组-力扣(LeetCode)
  • 京东科技集团寻求稳定币链上活动规划师
  • 150V降压芯片DCDC150V100V80V降压12V5V1.5A车载仪表恒压驱动H6203L惠洋科技
  • shape转换ersi json 修改增加多部件要素处理和空洞处理
  • 安卓\android程序开发之基于 Android 的校园报修系统的设计与实现
  • Android.mk教程
  • RFID系统:物联网时代的数字化管理中枢
  • 算法训练营day45 动态规划⑫ 115.不同的子序列、583. 两个字符串的删除操作、72. 编辑距离、编辑距离总结篇
  • Java -- 集合 --Collection接口和常用的方法
  • (3万字详解)Linux系统学习:深入了解Linux系统开发工具
  • leetcode 15 三数之和
  • 【《数字货币量化交易:Linux下策略回测平台的搭建》】
  • 2025-2026 专升本论文写作【八项规范】
  • [202404-B]画矩形
  • 微信小程序常用 API
  • Arcpy-重采样记录
  • B站直播, 拼接4个窗口,能否实现
  • 从源码看 Coze:Agent 的三大支柱是如何构建的?
  • 【优化】图片批量合并为word
  • 嵌入式学习day24