正则表达式
发布日期:2021-06-30 15:03:01 浏览次数:2 分类:技术文章

本文共 4993 字,大约阅读时间需要 16 分钟。

contents

1. 什么是正则表达式

1.1 正则表达式和通配符

  • 正则表达式用来在文件中匹配符合条件的字符串,正则是包含匹配。grep、awk、sed 等命令可以支持正则表达式。
  • 通配符用来匹配符合条件的文件名,通配符是完全匹配。ls、find、cp 这些命令不支持正则表达式,所以只能使用 shell 自己的通配符来进行匹配了。

可以在正则表达式中使用不同的特殊字符来定义特定的数据过滤模式。

root@jiaming-VirtualBox:/bin# ls -al d*-rwxr-xr-x 1 root root 121432 1月  25  2018 dash-rwxr-xr-x 1 root root 100568 1月  18  2018 date-rwxr-xr-x 1 root root  76000 1月  18  2018 dd-rwxr-xr-x 1 root root  84776 1月  18  2018 df-rwxr-xr-x 1 root root 133792 1月  18  2018 dir-rwxr-xr-x 1 root root  72000 1月   9  2020 dmesglrwxrwxrwx 1 root root      8 1月  31 14:40 dnsdomainname -> hostnamelrwxrwxrwx 1 root root      8 1月  31 14:40 domainname -> hostname-rwxr-xr-x 1 root root 170520 1月  22  2018 dumpkeys

1.2 正则表达式的类型

正则表达式不止有一种类型,编程语言的不同,Linux 实用工具的不同,主流应用的不同都会用不同的正则表达式类型。

在 Linux 中,有两种流行的正则表达式引擎:

  • POSIX 基础正则表达式引擎。(BRE模式)sed
  • POSIX 扩展正则表达式引擎。(ERE模式)gawk

大多数 Linux 工具都至少符合 BRE 引擎规范,但是有些工具(比如 sed 编辑器)只符合 BRE 引擎规范的子集。gawk 程序用 ERE 引擎来处理它的正则表达式。

元字符 作用
* 前一个字符匹配0次或任意多次。
. 匹配除了换行符外任意一个字符。
^ 匹配行首。^hello,匹配hello开头的行。
$ 匹配行尾。hello$,匹配hello结尾的行。
[] 匹配中括号中指定的任意一个字符,只匹配一个字符。 [aeiou]、[0-9]
[^] 匹配除了中括号内字符以外的任意一个字符。[^a-z]
\ 转义符。
{n} 表示其前面的字符恰好出现n次。[0-9]{4} 匹配4位数字。
{n,} 表示其前面的字符出现不小于n次。[0-9]{2,} 匹配2位及以上的数字。
{n,m} 表示前面的字符至少出现n次,最多出现m次。

2. 定义 BRE 模式

2.1 纯文本

正则表达式都区分大小写,正则表达式不关系模式在数据流中的位置,也不关心模式出现了多少次。

$ echo "This is a test" | sed -n '/test/p'This is a test$ echo "This is a test" | gawk '/test/{print $0}'This is a test

单词中间有两个空格的行匹配正则表达式模式,是用来查看文件中空格问题的好办法。

$ sed -n '/  /p' data.txtThis is   a line with too many spaces.

2.2 特殊字符

特殊字符:

.*[]^${}\+?|() # 不能在文本模式中单独使用这些字符,如果要使用某个特殊字符作为文本字符,就必须转义

2.3 锚字符

jiaming@jiaming-VirtualBox:~/Documents/bin$ cat data.txt This is a test line.this is another test line.A line that tests this feature.Yet more testing of this

2.3.1 锁定在行首

脱字符(^),定义从数据流中文本行的行首开始的模式,如果将其放到模式开头之外的其它位置,那么它就跟普通字符一样了。

jiaming@jiaming-VirtualBox:~/Documents/bin$ sed -n '/^this/p' data.txt this is another test line.

2.3.2 锁定在行尾

美元符($)定义了行尾锚点。

jiaming@jiaming-VirtualBox:~/Documents/bin$ sed -n '/line.$/p' data.txt This is a test line.this is another test line.jiaming@jiaming-VirtualBox:~/Documents/bin$ sed -n '/\.$/p' data.txt This is a test line.this is another test line.A line that tests this feature.

2.3.3 组合锚点

只看特定文本:

sed -n '/^this is a test$/p' data.txt

输出空白行:

sed '/^$/d' data.txt

2.4 点号字符

jiaming@jiaming-VirtualBox:~/Documents/bin$ cat data.txt This is a test line.this is another test line.A line that tests this feature.Yet more testing of this

特殊字符点号用来匹配除换行符之外的任意单个字符。

jiaming@jiaming-VirtualBox:~/Documents/bin$ sed -n '/.est/p' data.txt This is a test line.this is another test line.A line that tests this feature.Yet more testing of thisjiaming@jiaming-VirtualBox:~/Documents/bin$ sed -n '/.ests/p' data.txt A line that tests this feature.

2.5 字符组

jiaming@jiaming-VirtualBox:~/Documents/bin$ cat data.txt This is a test line.this is another test line.A line that tests this feature.Yet more testing of this

使用方括号来定义一个字符串。

jiaming@jiaming-VirtualBox:~/Documents/bin$ sed -n '/t[eh]/p' data.txtThis is a test line.this is another test line.A line that tests this feature.Yet more testing of this
echo "Yes" | sed -n '/[Yy][Ee][Ss]/p'

2.6 排除型字符组

只需要在字符组的开头加个脱字符。

sed -n '/[^ch]at/p' data.txt

2.7 区间

来制作一个过滤邮编的过滤器:

sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p' data.txt

2.8 特殊的字符组

处理定义自己的字符组外,BRE 还包含了一些特殊的字符组,可用来匹配特定类型的字符。

描述
[[:alpha:]] 匹配任意字母字符
[[:alnum:]] 匹配任意字母数字字符0~9、A~Z或a~z
[[:blank:]] 匹配空格或制表符
[[:digit:]] 匹配0-9之间的数字
[[:lower:]] 匹配小写字母
[[:upper:]] 匹配大写字母
[[:print:]] 匹配任意可打印字符
[[:punct:]] 匹配标点符号
[[:space:]] 匹配任意空白字符,空格,制表符,NL,FF,VT,CR
echo "abc123" | sed -n '/[[:digit:]]/p'abc123

2.9 星号

在字符后面放置星号表面该字符必须在匹配模式的文本中出现 0 次或多次。

echo "ik" | sed -n '/ie*k/p'ik

3. 扩展正则表达式

POSIX ERE 模式包括了一些可供 Linux 应用和工具使用的额外符号。gawk 能够识别 ERE 模式,但 sed 编辑器不能。

3.1 问号

问号表明前面的字符可以出现 0 次或 1 次,它不会匹配多次出现的字符。

echo "bet" | gawk '/bet?t/{print $0}'
echo "bet" | gawk '/b[ae]?t/{print $0}'

如果字符组中的字符出现了0次或1次,模式匹配就设立。但如果两个字符都出现了,或者其中一个字符出现了2次,模式匹配就不成立。

3.2 加号

加号表明前面的字符可以出现 1 次或多次,但必须至少出现 1 次,如果该字符没有出现,那么模式就不会匹配,同样可以使用字符组。

jiaming@jiaming-VirtualBox:~/Documents/bin$ echo "beeet" | gawk '/be+t/{print $0}'beeetjiaming@jiaming-VirtualBox:~/Documents/bin$ echo "beet" | gawk '/be+t/{print $0}'beetjiaming@jiaming-VirtualBox:~/Documents/bin$ echo "bet" | gawk '/be+t/{print $0}'betjiaming@jiaming-VirtualBox:~/Documents/bin$ echo "bt" | gawk '/be+t/{print $0}'jiaming@jiaming-VirtualBox:~/Documents/bin$

3.3 花括号

ERE 中的花括号允许你为可重复的正则表达式指定一个上限。

  • m:正则表达式准确出现m次。
  • m,n:正则表达式至少出现m次,至多n次。

这个特性可以精确调整字符或字符集在模式中具体出现的次数。

$ echo "bt" | gawk --re-interval '/be{1}t/{print $0}'
$ echo "beeet" | gawk --re-interval '/be{1,2}t/{print $0}'

3.4 管道符号

管道符号允许你检查数据流时,用逻辑或的方式指定正则表达式引擎用的两个或多个模式。

$ echo "The cat is asleep" | gawk '/cat|dog/{print $0}'

这个例子会在数据流中查找正则表达式 cat 或 dog。正则表达式和管道符号之间不能有空格。

$ echo "He has a hat." | gawk '/[ch]atdog/{print $0}'

3.5 表达式分组

正则表达式模式也可以用圆括号进行分组。当你将正则表达式模式分组时,该组会被视为一个标准字符。

$ echo "Sat" | gawk '/Sat(urday)?/{print $0}'

该模式能够匹配完整的 Staturday 或缩写Sat。

模式 (c|b)a(b|t)会匹配第一组中字母的任意组合以及第二组中字母的任意组合。

转载地址:https://jiaming.blog.csdn.net/article/details/104965905 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:毕业设计日志(18)
下一篇:Linux 中最常用的文本处理编辑器 —— 初识 sed 和 gawk

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年04月22日 18时54分44秒