Shell编程:正则表达式(通配符、正则概念、元字符、量词、示例等)



正则表达式 1

正则表达式(Regular Expressions,REGEXP)是一种由特殊字符和文本字符组成的模式,用于匹配和处理文本内容。与通配符不同,正则表达式不仅限于文件名匹配,还可以对文本内容中的字符进行匹配和筛选。正则表达式被许多程序和开发语言广泛支持,如 vimlessgrepsedawknginxmysql 等。

正则表达式的主要用途

匹配字符串(如命令输出、文件内容)中的特定模式。

通配符的主要用途

匹配文件名或目录名,但不能用于匹配文件内容。通配符主要用于用户在命令行中描述文件或目录名的匹配规则,例如查找以 “.sh” 结尾的文件。

通配符的常见用法

  • *匹配任意一个或多个字符,例如 ls *.txt 匹配所有以 .txt 结尾的文件。
  • ?匹配任意单个字符,例如 ls ?.txt 匹配所有文件名只有一个字符的 .txt 文件。
  • []匹配指定范围内的任意单个字符,例如 ls [a-z].txt 匹配所有以单个小写字母开头的 .txt 文件。

通配/转义/元字/连字符

通配符

通配符用于匹配文件名和字符串中的任意字符或字符集。常见的通配符包括:

  • *:匹配任意长度的任意字符(包括空字符)。

  • ?:匹配任意单个字符。

  • [ ]:匹配方括号内的任意一个字符或字符范围。

    例子*.txt 匹配所有以 .txt 结尾的文件;file?.doc 匹配文件名为 file1.docfileA.doc 等的文件。

转义符

转义符(通常是反斜杠 \)用于将元字符(如 *?$ 等)转义为普通字符,从而避免它们的特殊意义。

例子\* 表示字符 *,而不是通配符。

元字符

元字符是正则表达式中的特殊字符,用于表示特殊的匹配模式或操作。常见的元字符有 .*+?|[]() 等。

例子. 表示任意单个字符;[a-z] 表示匹配小写字母 az 的任意一个字符。

连字符

连字符(-)通常用于表示字符范围或连接两个字符,主要用于方括号表达式中。

例子[a-z] 表示从 az 的所有小写字母;0-9 表示所有数字字符。

正则表达式的类型

  1. 基本正则表达式(Basic Regular Expressions, BRE)
  2. **扩展正则表达式(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]

正则表达式的实例

匹配任意字符

  1. 匹配字符后跟任意字符的行:

    ls /opt | grep "t."
    

    匹配 t 后面跟任意一个字符的文件或目录名。

  2. 匹配字符后跟任意两个字符的行:

    grep 'r..t' /etc/passwd
    

    匹配 /etc/passwd 文件中包含 r、任意两个字符和 t 的行。

  3. 使用 grep 匹配任意字符 .

    echo abc | grep 'a.c'
    

    匹配字符串 abca 后跟任意单个字符,再跟 c 的模式。

    注意:加了管道符的 grep 均是正则,不是通配符。

匹配字符集合

  1. 使用 grep 匹配字符集合中的任意字符:

    ls | grep '[fhtx].txt'
    

    匹配当前目录下所有以 fhtx 字母开头并以 .txt 结尾的文件名。

  2. 使用通配符 [a-d] 匹配文件名范围:

    ls [a-d].txt
    

    匹配当前目录下所有文件名以 ad 或者 AD 字母开头并以 .txt 结尾的文件。

  3. 使用 grep 配合正则表达式匹配特定范围内的小写字符的文件名:

    ls | grep '[a-d].txt'
    

    匹配当前目录下所有文件名以小写字母 ad 开头并以 .txt 结尾的文件。

  4. 使用 grep 配合正则表达式匹配范围之外的字符:

    ls | grep '[^a-z].txt'
    

    匹配当前目录下所有文件名以非小写字母开头并以 .txt 结尾的文件。

  5. 使用 grep 匹配范围之外的字符集合:

    ls | grep '[^a.z].txt'
    

    匹配当前目录下所有文件名不以字符 az 开头且以 .txt 结尾的文件。

匹配特殊字符

  1. 匹配以 rc. 开头的文件(需要转义):

    ls /etc/ | grep 'rc\.'
    

    输出所有文件名以 rc. 开头的文件(. 需要转义)。

  2. 使用 grep 配合引号匹配特殊字符:

    echo abc | grep 'a\.c'
    

    匹配字符串 abc 中以 a 开头,后接一个点字符 .,最后是 c 的模式。

匹配字符类

  1. 使用 grep 匹配空白字符:

    grep [[:space:]] 123.txt
    

    匹配文件 123.txt 中所有包含空白字符(如空格、制表符)的行。

  2. 匹配大小写字母:

    ls | grep '[a-zA-Z]'
    

    匹配当前目录下所有文件名中包含小写字母 a-z 或大写字母 A-Z 的文件。

匹配混合字符集

  1. 使用 grep 配合正则表达式匹配指定的字符集范围:

    ls /etc/ | grep 'rc[.0-6]'
    

    匹配 /etc/ 目录下所有文件名中包含 rc 和任意一个字符 . 或者数字 0-6 的文件或目录。

  2. 使用 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 次)。

示例

示例:重复次数匹配

  1. 匹配字符 o 出现 2 次的字符串:

    echo google | grep 'go\{2\}gle'
    

    匹配字符 o 正好出现 2 次的字符串,输出 google

  2. 匹配字符 o 出现至少 2 次的字符串:

    echo gooooogle | grep 'go\{2,\}gle'
    

    匹配字符 o 出现 2 次或更多的字符串,输出 gooooogle

  3. 匹配字符 o 出现 2 到 5 次的字符串:

    echo gooooogle | grep 'go\{2,5\}gle'
    

    匹配字符 o 出现 2 到 5 次的字符串,输出 gooooogle

  4. 匹配字符 o 最多出现 5 次的字符串:

    echo goooooogle | grep 'go\{,5\}gle'
    

    匹配字符 o 最多出现 5 次的字符串,不输出结果(因为 goooooogleo 出现了 6 次)。

示例:通配符匹配

  1. 匹配字符 o 出现 0 次或多次的字符串:

    echo goooooogle | grep 'go*gle'
    

    匹配字符 o 出现 0 次到任意次数的字符串,输出 goooooogle

  2. 匹配字符串 ggle 中字符 o 出现 0 次:

    echo ggle | grep "go*gle"
    

    匹配字符 o 出现 0 次的字符串,输出 ggle

  3. 匹配字符 g 出现 1 次或多次的字符串:

    echo gggle | grep "go*gle"
    

    匹配字符 o 出现 0 次的字符串,输出 gggle

示例:任意字符匹配

  1. 匹配任意字符出现 0 次或多次的字符串:

    echo gdadadadgle | grep "g.*gle"
    

    .* 表示匹配任意字符出现任意次数,输出 gdadadadgle

示例:出现次数匹配

  1. 匹配字符 o 出现 0 次或 1 次的字符串:

    echo ggle | grep "go\?gle"
    

    \? 表示字符 o 出现 0 次或 1 次,输出 ggle

  2. 匹配字符 o 出现 1 次以上的字符串:

    echo google | grep "go\+gle"
    

    \+ 表示字符 o 出现 1 次或以上,输出 google

示例:IP 地址匹配

  1. ifconfig 输出中匹配 IPv4 地址:

    ifconfig ens33 | grep netmask | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+'
    

    使用 grep -o 和正则表达式匹配 ifconfig 输出中的 IPv4 地址。

  2. 匹配 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 位数字。


  • 19
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值