正则表达式预习
| 什么是正则表达式 |
| |
| 正则表达式就是为了处理大量的字符串而定义的一套规则和方法 |
| 通过定义的这些特殊符号的辅助,系统管理员就可以快速过滤,替换或输出需要的字符串 |
| Linux正则表达式一般以行为单位处理的 |

如何使用正则表达式
| 通常linux运维工作,都是面临大量带有字符串的内容, |
| 如: |
| 配置文件 |
| 程序代码 |
| 命令输出结果 |
| 日志文件 |
| |
| 且此类字符串内容,我们常会有特定的需要,查找出符合工作需要的特定的字符串,因此正则表达式就出现了 |
| |
| 正则表达式时一套规则和方法 |
| 正则工作时以单位进行,一次处理一行 |
| 正则表达式化繁为简,提高工作效率 |
| linux仅受三剑客(sed,awk,grep)支持,其他命令无法使用 |
| |
学习正则的注意事项
| 正则表达式应用非常广泛,很多编程语言都支持正则表达式,用于处理字符串提取数据 |
| Linux下普通命令无法使用正则表达式的,只能使用linux下的三个命令,结合正则表达式处理 |
| sed |
| grep |
| awk |
| 通配符是大部分普通命令都支持的,用于查找文件或目录 |
| 而正则表达式时通过三剑客命令文件(数据流)中过滤内容的,注意区别 |
| 以及注意字符集,需要设置 LC_ALL=C ,注意这一点很重要 |
关于字符集设置

| 作用是修改linux的字符集,通过locale命令可以查看本地字符集设置 |
| |
| linux通过如下变量设置程序运行的不同语言环境,如中文,英文环境 |
| |
| |
| [root@yuchao-tx-server ~] |
| LANG=en_US.UTF-8 |
| LC_CTYPE="zh_CN.UTF-8" |
| LC_NUMERIC="zh_CN.UTF-8" |
| LC_TIME="zh_CN.UTF-8" |
| LC_COLLATE="zh_CN.UTF-8" |
| LC_MONETARY="zh_CN.UTF-8" |
| LC_MESSAGES="zh_CN.UTF-8" |
| LC_PAPER="zh_CN.UTF-8" |
| LC_NAME="zh_CN.UTF-8" |
| LC_ADDRESS="zh_CN.UTF-8" |
| LC_TELEPHONE="zh_CN.UTF-8" |
| LC_MEASUREMENT="zh_CN.UTF-8" |
| LC_IDENTIFICATION="zh_CN.UTF-8" |
| LC_ALL=zh_CN.UTF-8 |
| 一般我们会使用 $LANG 变量来设置linux的字符集,一般设置为我们所在的地区,如 zh_CN.UTF-8 |
| |
| [root@bogon ~] |
| en_US.UTF-8 |
| |
为了让系统正确执行shell语句(由于自定义修改的不同语言环境,对一些特殊符号的处理区别,如中文输入法,英文输入法下的标点符号,导致shell无法执行)
我们会使用如下语句,恢复linux的所有的本地化设置,恢复系统到初始化的语言环境
| [root@bogon ~]# export LC_ALL=C |
| |
通配符和正则的区别
| 从语法上就记住,只有awk,grep,sed才识别正则表达式符号,其他都是通配符 |
| 从用法上区分 |
| 表达式操作的是文件,目录名(属于是通配符) |
| 表达式操作的是文件内容(正则表达式) |
| |
| 如下符号区别 |
| 通配符和正则表达式,都有 * ? [abcd] 符号 |
| 通配符中,都是用来标识任意的字符 |
| 如 ls *.log 可以找到 a.log b.log ccc.log |
| |
| |
| 正则中,都是用来表示这些符号前面的字符,出现的次数, |
| 如: grep 'a*' |
| |
| |
| |
| 实际案例 |
| 通配符,一般用于对文件名的处理,查找文件 |
| 如ls命令结合 * |
| 意思式匹配任意字符 |
| [root@bogon test]# ls *.log |
| a.log d.log g.log yc3.log yu1.log yu4.log yuyu.log |
| b.log e.log yc1.log yc4.log yu2.log yu5.log |
| c.log f.log yc2.log yc5.log yu3.log yuchao01.log |
| |
| |
| |
| |
| 而三剑客,结合*符号,是处理文件内容,如grep |
| 此时的*作用就不一样了 |

正则表达式分类
| 使用正则表达式的问题是,有两大类正则表达式规范,linux不同的应用程序,会使用不同的正则表达式 |
| 例如 |
| 不同的编程语言使用正则(python,java) |
| linux实用工具(sed,awk,grep) |
| 其他软件使用正则(mysql,nginx) |
| |
| 正则表达式是通过正则表达式引擎(regular expression engine)实现的,正则表达式引擎是一套底层软件,负责解释正则表达式模式并使用这些模式进行文本匹配 |
| |
| 在linux中,有两种流行的正则表达式引擎 |
| |
| 基于unix标准下的正则表达式符号规则有两类: |
| POSIX基础正则表达式(basic regular expression,BRE)引擎 |
| |
| POSIX扩展正则表达式(extended regular expression,ERE)引擎 |
| |
| 解释posix |
| POSIX(Portable Operating System Interface)是Unix系统的一个设计标准。 |
| 当年最早的Unix,源代码流传出去了,加上早期的Unix不够完善,于是之后出现了好些独立开发的与Unix基本兼容但又不完全兼容的OS,通称Unix-like OS |
两类,正则表达式符号
| linux规范将正则表达式分为了两种 |
| 基本正则表达式(BRE,basic,regular,expression) |
| |
| BRE对应元字符有 |
| ^ $ . [] * |
| |
| 其他符号式普通字符 |
| ; \ |
| |
| 扩展正则表达式(ERE、extended regular expression) |
| ERE在BRE基础上,增加了 |
| () {} ? + | 等元字符 |
| |
| 转义符 |
| 反斜杠 \ |
| 反斜杠用于在元字符前添加,使其成为普通字符 |
基本正则表达式(BRE)
| 测试文本数据 |
| |
| [root@bogon test]# cat chaoge666.txt |
| I am teacher yuchao. |
| I teach linux,python! |
| |
| I like english |
| |
| My website is http: |
| Our school site is https: |
| My qq num is 877348180 |
| |
| Good good study , day day up! |
| |
| |
| |
| |
| |
关于单引号、双引号
| 正则的模式,建议使用双引号 |
| 如果为涉及变量等,用单引号也不影响 |
grep与正则
| NAME |
| grep, egrep, fgrep - print lines matching a pattern |
| |
| SYNOPSIS |
| grep [OPTIONS] PATTERN [FILE...] |
| grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...] |
| |
| |
| 例如传入的pattern(模式是),我们可以统称你写的正则是模式 |
| ^m , 以m开头的行 |
| [root@bogon test] |
| 6:My website is http://yuchaoit.cn |
| 8:My qq num is 877348180 |
| |
^ 尖角符
| 语法 |
| 写于最左侧,如 |
| ^yu 逐行匹配,找到以yu开头的内容 |
| |
| 结合grep用法,-i 忽略大小写 |

| 结合grep的参数 -o 只显示一行中匹配出来的内容 |


$ 美元符
| 语法 |
| |
| word$ 匹配以word结尾的行 |
| |
| 匹配所有以字符n结尾的行 |

| 匹配所有以小数点 . 结尾的行,这里因为 . 也有特殊作用,因此得使用单引号,或者转义符 |

单、双引号区别
| 单引号,所见即所得,可以用于匹配如标点符号,还原其本义 |

| 双引号,能够识别linux得特殊符号,或变量,需要借助转义还原字符本义 |

^$ 匹配空行

. 点符
| . 匹配除了换行符以外所有得内容,字符+空格 ,除了换行符 |
| |
| . 点处理空格,换行 |
| |
| . 可以匹配到空格,以及任意字符 |

. 匹配除换行符得所有字符

. 代表任意一个字符
| 分别传入grep得模式 |
| |
| y. |
| |
| y.. 任意2个字符 |
| |
| 实践代码 |


.$ 匹配任意字符结尾

. 和转义符

\转义符
| 转义字符,让有特殊意义的字符,现出原形,还原其本义 |
| 如 |
| \. 还原为小数点 |
空格,换行,tab
| \n 匹配换行符 |
| \b 匹配单词边界,如我想从字符串“This is Regex”匹配单独的单词 “is”正则就要写 "\bis\b" |
| |
| \r 匹配回车符 |
| \t 匹配一个横向的制表符 |

* 星号

.* 符
| 匹配任意字符 |
| |
| .表示任意字符,*表示匹配前一个字符0次或多次 |
| 因此放一起,代表匹配每一行所有内容,包括空格,没有空行 |

^.* 符
| 语法 |
| |
| ^.* 表示以任意多个字符开头的行 |
| |
| 基础用法,^.* |



.*$ 符

| 你可以加上条件,例如 p.*$ |
| |
| 以p.*$结尾的行 |
| 等于,匹配出从p到结尾的所有内容 |

[ ]中括号
[abc]
| 【abc】匹配括号内的小写a,b,c字符 |
| |
| 关于到大小写的精准匹配,就别添加忽略大小写参数了 |

[a-z] , [A-Z],[a-zA-Z],[0-9]
| [a-z] 匹配所有小写单个字母 |
| |
| [A-Z] 匹配所有单个大写字母 |
| |
| [a-zA-Z] 匹配所有的单个大小写字母 |
| |
| [0-9] 匹配所有单个数字 |
| |
| [a-zA-Z0-9] 匹配所有数字和字母 |





abc 中括号取反
| 语法 |
| |
| [^abc] 排除中括号里的a,b,c,和单独的^符号,作用是不同的 |
| [^a-z] 排除小写字母 |

{ } 花括号(扩展正则)
| a\{n,m\} |
| |
| a\{n,m\} 重复字符a,n到m次 |
| |
| a\{1,3} 重复字符a,1到3次 |
| 实践 |
| 测试数据 |
| [root@bogon test]# cat chaoge777.txt |
| I am teacher yuchao. |
| I teach linux,python! |
| |
| I like english |
| |
| My website is http: |
| Our school site is https: |
| My qq num is 877348180 |
| |
| my qq num is not 87777773333344444888811188880000 |
| |
| Goog good study , day day up! |
| |


grep 默认不认识扩展正则 {}
| grep默认不认识扩展正则{},识别不到它的特殊作用,因此只能用转义符,让他成为有意义的字符 |

| 办法1 |
| 使用转义符 \{\} |
| |
| 办法2,让grep认识花括号,可以省去转义符 |
| 使用egrep命令 |
| 或者 grep -E |
| |
| 实践 |




扩展正则表达式(ERE)
| 这样记忆就好 |
| 基于正则表达式 |
| 属于早期正则表达式,支持一些基本的功能 |
| 与grep,sed命令结合使用 |
| |
| 扩展正则表达式 |
| 后来添加的正则表达式 |
| 和grep,awk命令结合 |
+ 加号
| 语法 |
| + |
| 重复前一个字符1次或多次 |
| 注意和*的区别,*是0次或多次 |
| |
| 匹配一次或者多次0,没有0的行是不会显示的 |
| |
| 0+ |
| 找出一个,或者多个数字零 |

| [0-9]+ |
| 从文中找出连续的数字,排除字母,特殊符号,空格 |

| [a-z]+ |
| 找出连续的小写字母,排除大写字母,标点符号,数字 |

| [root@bogon test] |
| 1:am |
| 1:teacher |
| 1:yuchao |
| 2:teach |
| 2:linux |
| 2:python |
| 4:like |
| 4:english |
| 6:y |
| 6:website |
| 6:is |
| 6:http |
| 6:yuchaoit |
| 6:cn |
| 7:ur |
| 7:school |
| 7:site |
| 7:is |
| 7:https |
| 7:apecome |
| 7:com |
| 8:y |
| 8:qq |
| 8:num |
| 8:is |
| 10:my |
| 10:qq |
| 10:num |
| 10:is |
| 10:not |
| 12:oog |
| 12:good |
| 12:study |
| 12:day |
| 12:day |
| 12:up |
| |
| [A-Za-z0-9]+ |
| 注意,这里添加了+号,就是找的连续的字母数字了,缺少+号则是每次匹配单个字符 |

| [^A-Za-z0-9]+ |
| 此写法,找出除了数字,大小写字母意外的内容,如空格,标点符号 |
| 可以使用-o参数,看到每次匹配的内容 |

*和+的区别
| 语法 |
| *是重复0次,重复多次,因此没匹配到的行也就过滤出来了 |
| |
| +是重复1次,多次,因此至少匹配到1次才看到 |
| |
| 例如,我们来找到字母o,看如下2个写法 |

go*d和go+d?d的区别
| 准备测试数据 |
| [root@bogon test]# cat god.log |
| I am God, I need you to good good study and day day up, otherwise I will send you to see Gd,oh sorry, gooooooooood! |
| |
| 关于寻找god,gooooood,gd的区别 |
| |
| go*d 可以有0个或者n个字母o |
| go*d 可以找到god,doof,gd,gooooooood |
| |
| go+d 可以有一个或n个字母o |
| go+d 可以找到god,good,gooooooood |
| |
| go?d 可以找到0个或者1个字母0 |
| go?d 可以找到gd,god |

| 或者符
查看内存信息

找出文件中的空行以及注释行
| 测试数据 |
| [root@bogon test]# cat chaoge999.txt |
| I am teacher yuchao. |
| I teach linux,python! |
| |
| I like english |
| |
| My website is http: |
| Our school site is https: |
| My qq num is 877348180 |
| |
| my qq num is not 87777773333344444888811188880000 |
| |
| #Goog good study , day day up! |
| # |
| #hello halo |
| |

( )括号,分组符
| 语法 |
| ()作用是将一个或者多个字符捆绑在一起,当做一个整体进行处理 |
| |
| 小括号功能之一是分组过滤被括起来的内容,括号内的内容表示一个整体 |
| |
| 括号()内的内容可以被后面的"\n"正则引用,n位数字,表示引用第几个括号的内容 |
| |
| \1: 表示从左侧起,第一个括号中的模式所匹配到的字符 |
| \2: 从左侧器,第二个括号中的模式所匹配到的字符 |
分组基本用法
| 测试数据 |
| [root@bogon test]# cat godd.log |
| I am God, I need you to good good study and day day up, otherwise I will send you to see Gd,oh sorry, gooooooooood! |
| I am glad to see you, god,you are a good god! |
| |
| 要求仅仅匹配出glad和good |
| 尝试使用正则 |
| grep -iE "gla|ood" godd.log |

| 并非我们想要的数据 |
| 我想要的是例如这样的匹配,只找出good,glad |
| grep -iE "glad|good" godd.log |

| 可以使用分组写法 |
| grep -iE "g(la|oo)d" godd.log |

分组与向后引用
| 语法 |
| () |
| 分组过滤,被括起来的内容表示一个整体,另外()的内容可以被后面的\n引用,表示引用第几个括号的内容 |
| |
| \n |
| 引用前面()里的内容,例如(abc)\1 表示匹配abcabc |
| 测试数据 |
| [root@bogon test] |
| I like my lover. |
| I love my lover. |
| He likes his lovers. |
| He love his lovers. |
| |
| 分组正则,提取love出现2次的行 |
| 拆解 |
| love,可以写为l..e |

| 提取/etc/passwd |
| 找出系统中几个特殊shell,专门用来开机,关机的用户 |
| 特点是,用户名,登录shell名字一样 |
| 可以用分区提取出 |

| 分组正则,提取特殊用户 |
| |
| 这部分正则需要拆开,更容易理解 |
| 1.提取冒号以外的字符,使用+可以匹配更多字母,没必要每次只处理一个 |
| grep -iE "[^:]+" /etc/passwd |
| |
| 2.使用\b匹配单词边界,提取出单词,示例用法,通常英文单词的边界是空格,标点符号 |
| [root@bogon test] |
| jie |
| |
| 3.继续提取用户文件,来确定第一个单词的边界 |

| 解释上图 |
| 正则拆解,根据写的顺序去理解 |
| [^:]+ 找出除了冒号以外的连续字符 |
| ^([^:]+\b) 对连续字符分组,且设定开头错点,以及单词边界,grep -Ei "^([^:]+\b)" /etc/passwd 这就等于找出第一个单词了 |
| "^([^:]+\b).*\1$" 找出如sync.*sync 这样(开头).*(结尾)的内容,使用分组,以及 \1 引用的语法 |
正则表达式总结
| 基础正则 BRE |
| ^ |
| $ |
| . |
| * |
| .* |
| [abc] |
| [^abc] |
| \{n,m\} |
BRE语法
| . 匹配单个任意字符,匹配 . 本身使用 \. |
| |
| * 前面的字符或模式重复任意次,匹配 * 本身使用 \* |
| |
| \{m\} 前面的字符或模式重复m次 |
| |
| \{m,n\} 前面的字符或模式重复m到n次 |
| |
| \{m,\} 前面的字符或模式重复m次以上 |
| |
| \(regexp\) 分组,将\(和\)之间的内容视为一个整体,有两个作用 |
| 1,配合前面的 * \{m,n\} 等量词使用,例如:ab\{2\} 匹配“abc”,而 \(ab\)\{2\}匹配“abab” |
| 2,向后引用(back references),使用\1 ~ \9 来引用第1~9个分组匹配的内容 |
| 3.例如:\(ab*\)\1 可以匹配“abab”, 也能匹配“abbbabbb” |
| |
| |
| ^ 放在正则表达式开头则匹配行首,其他位置匹配 ^ 本身 |
| |
| $ 放在正则表达式末尾则匹配行尾,其他位置匹配 $ 本省 |
| |
| [list] 自定义字符集,可以匹配 [ 和 ]之间出现的任意字符,例如:a[bcd] 可以匹配“ad,ac”或“cabba” |
| |
| 且支持使用char1-char2这种省略写法,例如:[0-9]* 可以匹配“1234567890”,[a-c]* 可以匹配“cabba” |
| |
| [^list] 同上,^取反的作用,匹配所有没有出现在 [ 和 ] 之间的其他字符 |
| |
| 另外其他风格的正则表达式中有诸如 \d \w \s 等速记符号(shorthand)表示一些常用字符集,BER和ERE均不支持这种写法,取而代之的是POSIX标准中定义的字符集: |
| |
POSIX正则语法表
| POSIX Description ASCII Shorthand |
| [:alnum:] 数字和字母 [a-zA-Z0-9] |
| [:alpha:] 字母 [a-zA-Z] |
| [:ascii:] ASCII字符 [\x00-\x7F] |
| [:blank:] 空格和 Tab [ \t] \h |
| [:cntrl:] 控制字符 [\x00-\x1F\x7F] |
| [:digit:] 数字 [0-9] \d |
| [:graph:] 可视字符 [\x21-\x7E] |
| [:lower:] 小写字母 [a-z] \l |
| [:print:] 可打印字符 [\x20-\x7E] |
| [:punct:] 标点符号 [!"#$%&'()*+, -./:;<=>?@[ ]^_‘{\ }~] |
| [:space:] 所有空白字符 [ \t\r\n\v\f] \s |
| [:upper:] 大写字母 [A-Z] \u |
| [:word:] 单词 [A-Za-z0-9_] \w |
| [:xdigit:] 十六进制数 [A-Fa-f0-9] |
| |
| 注意:[ 和 ] 也是该字符集名称的一部分,即在使用中和 [0-9] 等价的是 [[:digit:]] 而不是 [:digit:] |
| |
ERE语法
| ERE和BRE的最显著的区别是ERE中所有元字符(metacharacters)均不需要使用 \ 进行转义,即用 {m,n} 替代 \{m,n\} , (regexp) 替代 \(regexp\) (当然分组向后引用依旧是 \1 ~ \9)。 |
| |
| 此外ERE还在BRE基础上增加了以下语法: |
| |
| ? 前面的字符或模式重复0或1次 |
| |
| + 前面的字符或模式重复1次及以上 |
| |
| |,regexp1|regexp2匹配regexp1或regexp2 |
GNU扩展的BRE
| 实际上现代Linux发行版中使用的 grep sed awk 等工具均由GNU提供,GNU在实现对BRE进行了扩展,增加了 \? \+ \| 使得BRE和ERE的区别仅剩元字符是否需要转义 |
| |
| 个人认为,BRE现在存在的主要意义还是向下兼容,避免修改已经投入使用的正则表达式 |
总结grep
| egrep被淘汰,使用grep -E |
| 可以使用grep -o参数,查找每次匹配的结果 |
| 正则需要在练习中理解器含义,无法死记硬背 |
| 后面结合sed,awk发挥更多正则作用 |
正则记忆表



【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)