1. Shell 正则表达式概述
1.1 正则表达式是什么
正则表达式 (regular expression)是一些具体有特殊含义的符号,组合在一起的共同描述字符或字符串的方法,通俗来讲正则为描述同一类事物的规则,例如我们生活中描述可以飞行的是事物,则满足这条规则的可以是鸟,蝴蝶,也可以是飞机等。
在 Linux 系统中,正则表达式通常用来对字符或字符串来进行处理,它是用于描述字符排列或匹配模式的一种语言规则。
1.2 为什么要用正则表达式
我们知道正则表达式是一个描述字符排列或模式匹配的规则,我们可以利用它来制定自己的规则,获取到我们想要的结果等。在后续的 Shell 三剑客 grep/awk/sed Shell 的学习中,我们会结合正则表达式与这些命令进行结合使用,来实现更强大的文本处理功能。正则表达式是我们 Shell 学习的核心也是难点,在 Linux 中一切皆文件,多文件的处理可以覆盖我们日常工作的 90%,所有熟练掌握正则表达式显得尤为重要,在之后灵活配合其他命令可以非常方便的满足我们的日常处理需求。
2. Shell 正则表达操作
在学习正则表达式的操作之前我们需要了解下 POSIX 及正则表达式的分类。
2.1 预备知识
2.1.1 POSIX
POSIX 称为:Portable Operating System Interface(末尾增加 X 只是为了更流畅)的缩写,后来被 IEEE 采纳,由于在早期 Unix 系统时代各厂商发布不同版本的操作系统,各版本之间存在着产品的差异,之后 IEEE 发布了一套 Unix 和类 Unix 系统工作方式规范,至此各常见遵循此规范来达到软件兼容的效果。
2.1.2 正则表达式分类
正则表达式常见的有两种分类:
- 基本正则表达式:Basic Regular Expression 又叫 Basic RegEx 简称 BREs,在基本正则表达式中作用的元字符为:^ 、$、 . 、[、] 、* ;
- 扩展正则表达式:Extended Regular Expression 又叫 Extended RegEx 简称 EREs,其为在基本正则表达式上新增了 (、) 、{ 、} 、?、 + 、等元字符元字符,使得正则表达式更加简洁易用。
2.1.3 字符
在学习正则表达式前需要先学习字符。
- POSIX 字符
通用 POSIX 原字符如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 特殊字符
在扩展正则表达式中加上 \
则被认为其具有特殊含义:
- 1
- 2
- 3
- 4
- 5
2.1.4 区别
- 基本正则表达元字符:只有 ^$.*[];
- 扩展正则表达式元字符:^$.[]*+(){}?|;
- 扩展正则表达式对于 {m,n} 和 () 不需要再向基本正则表达式需要
\
来转译。
2.2 正则表达式操作
在 Linux 中正则表达式用来处理文本,在此我们使用 grep 工具对正则表达式进行操作,grep 为文本过滤工具,在 grep 命令中默认使用的时候基本正则表达式,可以使用选项 -E
来开启扩展正则表达式,按照指定的正则表达式取出我们需求的内容。
2.2.1 字符匹配
在字符匹配前需要先学习。
.
: 匹配任意单个字符,例如:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
.
匹配必须为字母 s 与 e 中有任意单个字符。
[]
: 匹配指定中括号范围内的任意单个字符,例如:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
中括号内可以利用元字符来表示。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
如上,匹配的元字符取反,也就是不包含匹配的内容。
2.2.2 次数匹配
次数匹配用在指定的字符后面,表示指定匹配到前面的字符出现多少次。
*
: 匹配前面的字符任意次(0 次或无数次),例如:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
如上匹配字符 s,0 次或多次。
\?
: 匹配前面的字符 0 次或 1 次,例如:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
如上匹配 s 可以存在 0 次,或者存在 1 次之后需要有 h 字符,注意利用选项 -E
开启扩展正则表达式,相较于基本正则表达式不需要 \
。
+
: 匹配前面的字符至少 1 次,例如:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如上匹配 s 至少存在 1 次或无数次。
\{m\,}
: 匹配前面的字符至少 m 次(默认工作在贪婪模式下,? 取消贪婪模式),例如:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
匹配字符 s,最少 1 次。
\{,n}
: 匹配前面的字符最多 n 次(默认工作在贪婪模式下,? 取消贪婪模式),例如:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
匹配字符 s,最多 2 次。
\{m,n\}
: 匹配前面的字符至少 m 次,至多 n 次,例如:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
匹配字符 s,1-2 次之间。
.*
: 匹配任意字符任意次数。
2.2.3 位置锚定
^
: 行首锚定,用于模式最左边,例如:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
匹配以 s 开头的行。
$
: 行尾锚定,用于模式最右边,例如:
- 1
- 2
- 3
- 4
- 5
- 6
匹配以 h 结尾的行。
\<
或\b
: 锚定词首,用于单词模式左侧,例如:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
可以看到此刻匹配是以单词模式,没有匹配 helloroot。
\>
或\b
: 锚定词尾,用于单词模式右侧,例如:
- 1
- 2
- 3
- 4
2.2.4 分组引用
()
分组:将一个或多个字符当成一个整体来进行后续处理;1…数字
引用:从左侧起,引用第一个左括号以及与之匹配右括号之间的模式所匹配到的字符,后向引用,例如:
- 1
利用 () 将 root 引用起来,后面利用数字 1 引用。
3. 实例
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
4. 注意事项
- 正则表达式中基本正则表达式与扩展正则表达式配合其它操作,能够千变万化,非常灵活,根据不同场景可以进行正向匹配和反向匹配;
- 正则表达式配合命令通常为三剑客 grep/awk/sed 等,后期灵活进行组合达到事半功倍的效果;
- 我们在文本模式匹配的时候可以考虑使用扩展的正则表达式,从而避免使用过多的转义字符。
5 小结
正则表达式可谓 Shell 中的精华,其实在其他语言中也很通用,需要进行勤加练习才能达到熟练掌握,注意区分基本正则表达式与扩展正则表达式的语法区别,配合其他工具灵活运用。在不同场景可以利用命令选项配合使用,在后期 Shell 脚本三剑客中也会频繁出现正则表达式,攻克正则表达式这个难关,Shell 脚本编程就已经事半功倍。