Shell编程:正则表达式(通配符、正则概念、元字符、量词、示例等)
文章目录
- 正则表达式 1
- 通配符的常见用法
- 通配/转义/元字/连字符
- 通配符
- 转义符
- 元字符
- 连字符
- 正则表达式的类型
- 元字符(字符匹配)
- 正则表达式的实例
- 匹配任意字符
- 匹配字符集合
- 匹配特殊字符
- 匹配字符类
- 匹配混合字符集
- 思考:正则表达式中的差异
- 正则表达式表示次数(量词)
- 量词符号及其解释
- 示例
- 示例:重复次数匹配
- 示例:通配符匹配
- 示例:任意字符匹配
- 示例:出现次数匹配
- 示例:IP 地址匹配
正则表达式 1
正则表达式(Regular Expressions,REGEXP)是一种由特殊字符和文本字符组成的模式,用于匹配和处理文本内容。与通配符不同,正则表达式不仅限于文件名匹配,还可以对文本内容中的字符进行匹配和筛选。正则表达式被许多程序和开发语言广泛支持,如 vim
、less
、grep
、sed
、awk
、nginx
、mysql
等。
正则表达式的主要用途:
匹配字符串(如命令输出、文件内容)中的特定模式。
通配符的主要用途:
匹配文件名或目录名,但不能用于匹配文件内容。通配符主要用于用户在命令行中描述文件或目录名的匹配规则,例如查找以 “.sh” 结尾的文件。
通配符的常见用法
*
:匹配任意一个或多个字符,例如ls *.txt
匹配所有以.txt
结尾的文件。?
:匹配任意单个字符,例如ls ?.txt
匹配所有文件名只有一个字符的.txt
文件。[]
:匹配指定范围内的任意单个字符,例如ls [a-z].txt
匹配所有以单个小写字母开头的.txt
文件。
通配/转义/元字/连字符
通配符
通配符用于匹配文件名和字符串中的任意字符或字符集。常见的通配符包括:
-
*
:匹配任意长度的任意字符(包括空字符)。 -
?
:匹配任意单个字符。 -
[ ]
:匹配方括号内的任意一个字符或字符范围。例子:
*.txt
匹配所有以.txt
结尾的文件;file?.doc
匹配文件名为file1.doc
、fileA.doc
等的文件。
转义符
转义符(通常是反斜杠 \
)用于将元字符(如 *
、?
、$
等)转义为普通字符,从而避免它们的特殊意义。
例子:\*
表示字符 *
,而不是通配符。
元字符
元字符是正则表达式中的特殊字符,用于表示特殊的匹配模式或操作。常见的元字符有 .
、*
、+
、?
、|
、[]
、()
等。
例子:.
表示任意单个字符;[a-z]
表示匹配小写字母 a
到 z
的任意一个字符。
连字符
连字符(-
)通常用于表示字符范围或连接两个字符,主要用于方括号表达式中。
例子:[a-z]
表示从 a
到 z
的所有小写字母;0-9
表示所有数字字符。
正则表达式的类型
- 基本正则表达式(Basic Regular Expressions, BRE)
- **扩展正则表达式(Extended Regular Expressions, ERE)(**支持更多的元字符及其功能)
元字符(字符匹配)
正则表达式中的元字符用于表示字符匹配的规则和范围:
.
:匹配任意单个字符(可以是一个汉字)。()
:括号作为一个组匹配。使用转义符时,表示字符字面意义\(\)
。[]
:匹配指定范围内的任意单个字符,例如[dn]
,[0-9]
,[a-zA-Z]
,[:alpha:]
。[^]
:匹配指定范围外的任意单个字符,例如[^dn]
,[^a.z]
。[[:alnum:]]
:匹配字母和数字,即[0-9]
和[a-zA-Z]
。[[:alpha:]]
:匹配任何英文大小写字符,即[A-Z]
和[a-z]
。[[:lower:]]
:匹配小写字母,例如[[:lower:]]
等价于[a-z]
。[[:upper:]]
:匹配大写字母,例如[[:upper:]]
等价于[A-Z]
。[[:blank:]]
:匹配空白字符(空格和制表符)。[[:space:]]
:匹配包括空格、制表符、水平和垂直制表符、换行符、回车符等各种类型的空白字符,比[[:blank:]]
包含的范围广。[[:cntrl:]]
:匹配不可打印的控制字符(退格、删除、警铃等)。[[:digit:]]
:匹配十进制数字。[[:xdigit:]]
:匹配十六进制数字。[[:graph:]]
:匹配可打印的非空白字符。[[:print:]]
:匹配可打印字符。[[:punct:]]
:匹配标点符号。\w
:匹配单词构成部分,等价于[_[:alnum:]]
。\W
:匹配非单词构成部分,等价于[^_[:alnum:]]
。\S
:匹配任何非空白字符,等价于[^ \f\n\r\t\v]
。\s
:匹配任何空白字符,包括空格、制表符、换页符等,等价于[ \f\n\r\t\v]
。
正则表达式的实例
匹配任意字符
-
匹配字符后跟任意字符的行:
ls /opt | grep "t."
匹配
t
后面跟任意一个字符的文件或目录名。 -
匹配字符后跟任意两个字符的行:
grep 'r..t' /etc/passwd
匹配
/etc/passwd
文件中包含r
、任意两个字符和t
的行。 -
使用
grep
匹配任意字符.
:echo abc | grep 'a.c'
匹配字符串
abc
中a
后跟任意单个字符,再跟c
的模式。注意:加了管道符的 grep 均是正则,不是通配符。
匹配字符集合
-
使用
grep
匹配字符集合中的任意字符:ls | grep '[fhtx].txt'
匹配当前目录下所有以
f
、h
、t
、x
字母开头并以.txt
结尾的文件名。 -
使用通配符
[a-d]
匹配文件名范围:ls [a-d].txt
匹配当前目录下所有文件名以
a
到d
或者A
到D
字母开头并以.txt
结尾的文件。 -
使用
grep
配合正则表达式匹配特定范围内的小写字符的文件名:ls | grep '[a-d].txt'
匹配当前目录下所有文件名以小写字母
a
到d
开头并以.txt
结尾的文件。 -
使用
grep
配合正则表达式匹配范围之外的字符:ls | grep '[^a-z].txt'
匹配当前目录下所有文件名以非小写字母开头并以
.txt
结尾的文件。 -
使用
grep
匹配范围之外的字符集合:ls | grep '[^a.z].txt'
匹配当前目录下所有文件名不以字符
a
或z
开头且以.txt
结尾的文件。
匹配特殊字符
-
匹配以
rc.
开头的文件(需要转义):ls /etc/ | grep 'rc\.'
输出所有文件名以
rc.
开头的文件(.
需要转义)。 -
使用
grep
配合引号匹配特殊字符:echo abc | grep 'a\.c'
匹配字符串
abc
中以a
开头,后接一个点字符.
,最后是c
的模式。
匹配字符类
-
使用
grep
匹配空白字符:grep [[:space:]] 123.txt
匹配文件
123.txt
中所有包含空白字符(如空格、制表符)的行。 -
匹配大小写字母:
ls | grep '[a-zA-Z]'
匹配当前目录下所有文件名中包含小写字母
a-z
或大写字母A-Z
的文件。
匹配混合字符集
-
使用
grep
配合正则表达式匹配指定的字符集范围:ls /etc/ | grep 'rc[.0-6]'
匹配
/etc/
目录下所有文件名中包含rc
和任意一个字符.
或者数字0-6
的文件或目录。 -
使用
grep
配合正则表达式匹配以rc.
开头的文件(需要转义):ls /etc/ | grep 'rc[.0-6].'
匹配
/etc/
目录下所有文件名中包含rc
,紧接着是字符.
(或数字0-6
),然后后跟任意一个字符的文件或目录。
思考:正则表达式中的差异
grep "rc[.0-6]"
与grep "rc[.0-6]."
的区别:rc[.0-6]
:匹配以rc
开头,后接.
或0-6
中任一字符的字符串。rc[.0-6].
:匹配以rc
开头,后接.
或0-6
中任一字符,再接一个任意字符的字符串。
正则表达式表示次数(量词)
量词(Quantifiers)用于指定一个字符或子表达式在匹配过程中应出现的次数。
量词符号及其解释
*
:匹配前面的字符任意次(包括 0 次),贪婪模式:尽可能长地匹配。.*
:匹配任意长度的任意字符,包括空字符。\?
:匹配前面的字符出现 0 次或 1 次,即可有可无。\+
:匹配前面的字符出现至少 1 次,即至少出现 1 次或更多次。\{n\}
:匹配前面的字符正好出现n
次。\{m,n\}
:匹配前面的字符至少出现m
次,至多出现n
次。\{,n\}
:匹配前面的字符至多n
次(不超过n
次)。\{n,\}
:匹配前面的字符至少n
次(不少于n
次)。
示例
示例:重复次数匹配
-
匹配字符
o
出现 2 次的字符串:echo google | grep 'go\{2\}gle'
匹配字符
o
正好出现 2 次的字符串,输出google
。 -
匹配字符
o
出现至少 2 次的字符串:echo gooooogle | grep 'go\{2,\}gle'
匹配字符
o
出现 2 次或更多的字符串,输出gooooogle
。 -
匹配字符
o
出现 2 到 5 次的字符串:echo gooooogle | grep 'go\{2,5\}gle'
匹配字符
o
出现 2 到 5 次的字符串,输出gooooogle
。 -
匹配字符
o
最多出现 5 次的字符串:echo goooooogle | grep 'go\{,5\}gle'
匹配字符
o
最多出现 5 次的字符串,不输出结果(因为goooooogle
中o
出现了 6 次)。
示例:通配符匹配
-
匹配字符
o
出现 0 次或多次的字符串:echo goooooogle | grep 'go*gle'
匹配字符
o
出现 0 次到任意次数的字符串,输出goooooogle
。 -
匹配字符串
ggle
中字符o
出现 0 次:echo ggle | grep "go*gle"
匹配字符
o
出现 0 次的字符串,输出ggle
。 -
匹配字符
g
出现 1 次或多次的字符串:echo gggle | grep "go*gle"
匹配字符
o
出现 0 次的字符串,输出gggle
。
示例:任意字符匹配
-
匹配任意字符出现 0 次或多次的字符串:
echo gdadadadgle | grep "g.*gle"
.*
表示匹配任意字符出现任意次数,输出gdadadadgle
。
示例:出现次数匹配
-
匹配字符
o
出现 0 次或 1 次的字符串:echo ggle | grep "go\?gle"
\?
表示字符o
出现 0 次或 1 次,输出ggle
。 -
匹配字符
o
出现 1 次以上的字符串:echo google | grep "go\+gle"
\+
表示字符o
出现 1 次或以上,输出google
。
示例:IP 地址匹配
-
从
ifconfig
输出中匹配 IPv4 地址:ifconfig ens33 | grep netmask | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+'
使用
grep -o
和正则表达式匹配ifconfig
输出中的 IPv4 地址。 -
匹配 IPv4 地址范围(1 到 3 位数的数字):
ifconfig ens33 | grep netmask | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
使用更灵活的正则表达式匹配 IP 地址段中的 1 到 3 位数字。