Shell的正则表达式
1 正则表达式简介
1.1 什么是正则表达式
在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。
正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。
正则表达式又称正规表达式、常规表达式。在代码中常简写为 regex、regexp 或 RE。
正则表达式是使用单个字符串来描述、匹配一系列符合某个与语法规则的字符串,简单来说,是一种匹配字符串的方法,通过一些特殊符号,实现快速查找、删除、替换某个特定字符串。
1.2 正则表达式示例
0和非0打头的一串数字:^0$|^[1-9][0-9]*$
验证汉字:^[\u4e00-\u9fa5]{0,}$
1.3 正则表达式作用
- 测试字符串内的模式
测试输入字符串,以查看字符串内是否出现电话号码模式或信用卡号码模式。这称为数据验证。
- 替换文本
使用正则表达式来识别文档中的特定文本,完全删除该文本或者用其他文本替换它。
- 基于模式匹配从字符串中提取子字符串
查找文档内或输入域内特定的文本。
1.4 应用领域
正则表达式已经在很多软件中得到广泛的应用,包括 *nix(Linux, Unix等)、HP 等操作系统,C#、Java 等开发环境,以及很多的应用软件中,都可以看到正则表达式的影子。
C# 正则表达式、Java 正则表达式、JavaScript 正则表达式、Python 正则表达式等
对于系统管理员来说,正则表达式则是必备技能之一。通过正则表达式快速提取“有问题”的信息。如此一来,可以将运维工作变得更加简单、方便。
1.5 正则表达式语法综述
正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为"元字符")组成的文字模式。
元字符不表示字符字面意义,而表示控制或通配的功能,类似于增强版的通配符功能。
但与通配符不同,通配符功能是用来处理文件名,而正则表达式是处理文本内容中字符。
模式描述在搜索文本时要匹配的一个或多个字符串。
正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
在 Shell 中,正则表达式使用的是 POSIX 扩展正则表达式语法(extended regular expression syntax)。
常见的元字符和字符类如下:
字符 | 说明 |
---|---|
. | 匹配一个任意字符(\n除外) |
^ | 匹配行首 |
$ | 匹配行尾 |
* | 匹配前一个字符出现0次或多次 |
+ | 匹配前一个字符出现1次或多次 |
? | 匹配前一个字符出现0次或1次 |
| | 表示或操作 |
[charset] | 匹配字符集中的任意一个字符 |
[^charset] | 匹配非字符集中的任意一个字符 |
[a-z] | 匹配a~z范围内的任意一个小写字母 |
[A-Z] | 匹配A~Z范围内的任意一个大写字母 |
[0-9] | 匹配0-9范围内的任意一个数字 |
\s | 匹配任意空白字符,包括空格、制表符、换行符等 |
\S | 匹配任意非空白字符 |
2 正则表达式基础
2.1 基础正则表达式常见元字符
- \:转义字符(
用于取消特殊符号的含义,如:\n、
\$
-
^:匹配字符串开始的位置
-
$:匹配字符串结束的位置
-
.:匹配除\n之外的任意一个字符
-
*:匹配前面表达式重复0次或多次
-
[list]:匹配list列表中的一个字符
-
[^list]:匹配任意非list列表中的一个字符
-
\{n\}
:匹配前面的表达式n次 -
\{n,\}
:匹配前面的表达式至少n次 -
\{,n\}
:匹配前面的表达式最多n次 -
\{n,m\}
:匹配前面的表达式n到m次 -
\w:匹配包括下划线的任何单词字符,等价于[a-zA-Z0-9_]
-
\W:匹配任何非单词字符,等价于
[^a-zA-Z0-9_]
-
\s:空白符,如:空格符、换行符、回车符等
-
\S:非空白符
-
支持的工具:
grep、egrep、sed、awk
2.2 查找特定字符和组合
从 test.txt 文件中查找出特定字符“the”所在位置
-n表示显示行号
-i表示不区分大小写
命令执行后,符合匹配标准的字符,字体颜色会变为红色
grep -n 'the' test.txt
grep -i 'the' test.txt
2.2.1 通配符[]
[charset]为候选字符集,即匹配其中的一个即可
grep -n 'sh[io]rt' test.txt
[io] 表示匹配 i 或者 o
# 查找包含数字的行
grep -n '[0-9]' test.txt
2.2.2 反向选择[^]
^
在[]中时,表示取反,如[^a]
表示不是a
# 查找oo前面不存在数字字符串
grep -n '[^0-9]oo' test.txt
# oo前面不存在小写字母
grep -n '[^a-z]oo' test.txt
# oo前面不存在大写字母
grep -n '[^A-Z]oo' test.txt
2.2.3 行首字符^
# 以the字符串为行首的行
grep -n '^the' test.txt
# 小写字母开头的行
grep -n '^[a-z]' test.txt
# 大写字母开头的行
grep -n '^[A-Z]' test.txt
# 不以字母开头的行
grep -n '^[^a-zA-Z]' test.txt
2.2.4 行尾字符$
# 以s结尾的行
grep -n 's$' test.txt
# 空白行
grep -n '^$' test.txt
# 不是查询以ti开头,以ti结尾的行,而是只有ti的行
grep –n ‘^ti$’ test.txt
2.2.5 边界字符\b
查询以指定字符为边界的单词
# 以s开头的单词
grep –n ‘\bs’ test.txt
# 以s结尾的单词
grep –n ‘s\b’ test.txt
- \B 非边界
2.2.6 任意字符.
在正则表达式中小数点(.)也是一个元字符,匹配除\n之外的任意的一个字符。
# 以 w 开头 d 结尾,共有四个字符的字符串
grep -n 'w..d' test.txt
2.2.7 重复字符*
匹配前面子表达式0次或者多次
# 包含至少两个以上 o 的字符串
grep -n 'ooo*' test.txt
# 以 w 开头 d 结尾,中间包含至少一个 o 的字符串
grep -n 'woo*d' test.txt
# 以 w 开头 d 结尾,中间的字符可有可无的字符串
grep -n 'w.*d' test.txt
2.2.8 连续字符范围{}
\{n\}
:匹配前面的表达式n次
# 两个 o 的字符
grep -n 'o\{2\}' test.txt
\{n,\}
:匹配前面的表达式至少n次
# 以 w 开头以 d 结尾,中间包含至少2个 o 的字符串
grep -n 'wo\{2,\}d' test.txt
\{,n\}
:匹配前面的表达式最多n次
# 以 w 开头以 d 结尾,中间包含最多5个 o 的字符串
grep -n 'wo\{,5\}d' test.txt
\{n,m\}
:匹配前面的表达式n到m次
# 以 w 开头以 d 结尾,中间包含 2~5 个 o 的字符串
grep -n 'wo\{2,5\}d' test.txt
3 正则表达式进阶
3.1 正则表达式元字符扩展
- +:匹配前面表达式1次以上
- ?:匹配前面表达式0次或1次
- ():将括号中的字符串看作一个整体
- |:以或的方式匹配字符串
- 支持的工具:
egrep、awk、grep -E、sed -r
3.2 egrep命令
grep 命令仅支持基础正则表达式,如果使用扩展正则表达式,需要使用 egrep或 awk 命令。
egrep 命令与 grep 命令的用法基本相似。egrep 命令是一个搜索文件获得模式,使用该命令可以搜索文件中的任意字符串和符号,也可以搜索一个或多个文件的字符串,一个提示符可以是单个字符、一个字符串、一个字或一个句子。
# 大小写不敏感搜索
egrep -i "test" test.txt
# 查找以大写字母开头的行
egrep "^[A-Z]" test.txt
# 查找包含三个或更多连续 o 的行
egrep "o{3,}" test.txt
3.2.1 |示例
# 包含 test 或 than的行
egrep -n 'test|than' test.txt
3.2.2 ()示例
# 包含至少两个连续相同字符的行
egrep -n '(.)\1' test.txt
(.):这是一个捕获组(capturing group)。它捕获任意单个字符,并将其存储在一个临时缓冲区中。括号 ()用于定义捕获组。
\1: 这是对第一个捕获组的反向引用(backreference)。它表示与第一个捕获组中捕获的
字符相同的内容。
(.)\1:捕获任意一个字符,然后查找紧跟在这个字符后面的相同字符。
3.2.3 +示例
# 包含两个或更多连续 l 的行
egrep -n 'll+' test.txt