shell-正则表达式

正则基础

元字符

POSIX BRE 和 ERE 都支持的 meta 字符

字符 BRE/ERE 模式含义
^ BRE,ERE 锚定行或字符串的开始,如:‘^grep’ 匹配所有以 grep 开头的行。BRE:仅仅在正则表达式结尾处具有特殊含义;ERE:在正则表达式任何地方都有特殊含义
$ BRE,ERE 锚定行或字符串的结束,如:‘grep$’ 匹配所有以 grep 结尾的行。BRE:仅仅在正则表达式结尾处具有特殊含义;ERE:在正则表达式任何地方都有特殊含义
. BRE,ERE 匹配一个非换行符的字符,如:‘gr.p’ 匹配 gr 后接一个任意字符,然后是 p
* BRE,ERE 匹配零个或多个先前字符。如:‘*grep’ 匹配所有一个或多个空格后紧跟 grep 的行。.*一起使用代表任意字符
[…] BRE,ERE 匹配中括号内任意一个字符。如果 ^ 符号位于方括号的开始,则不匹配括号内的任意字符。如:[^a-zA-Z] 不匹配 a-z和A-Z中任意字符
\ BRE,ERE 用于打开或关闭后续字符的特殊含义。如:\(\)

BRE:基本正则表达式;ERE扩展正则表达式

POSIX BRE 和 ERE 支持不同的 meta 字符

字符 BRE/ERE 模式含义
\(\) BRE 标记匹配字符,这个元字符将\(和\)之间的模式存储在保留空间中,在后续的正则表达式中可以通过转义序列引用这些匹配的模式。如‘\(grep\).*\1’ 就匹配两个 grep 中间带有任意数目的字符,第二个 grep 使用 \1来引用。最多可以保存 9 个独立的模式,即从 \1 到 \9
\n BRE 重复在 \(与\)内的第 n 个模式。n 为 1 到 9,n是数字
x\{m,n\} BRE 区间表达式,匹配 x 字符出现的次数区间。x\{n\}是指 x 出现了 n 次;x\{m,\} 是指最少出现 m 次;x\{m,n\} 是指至少出现 m 次,至多出现 n 次
x{m,n} ERE 和上一条一样,不过没有反斜杠
+ ERE 匹配前面正则表达式的一个或多个实例
? ERE 匹配前面正则表达式的零个或一个实例
&#x7C ERE 匹配前面或后面的正则表达式
() ERE 匹配用括号括起来的正则表达式群

grep 程序支持的 meta 字符 plus

字符 模式含义
\< 锚定单词的开始,如:‘\<grep’ 匹配包含以 grep 开头的单词的行
\> 锚定单词的结束,如:‘grep\>’ 匹配包含以 grep 结尾的单词的行
\w 匹配文字和数字字符,也就是[A-Za-z0-9],如:‘G\w*p’ 匹配以 G 后跟零个或多个文字或数字字符,然后是p
\W \w 的反置形式,匹配一个或多个非单词字符,如点号、句号等
\b 单词锁定符,如 ‘\bgrep\b’ 值匹配 grep

正则表达式实例

1
2
3
4
5
ls -l | grep '^d' # 通过管道过滤 ls -l 输出的内容,只显示以 d(文件为目录) 开头的行
grep 'test' d* # 显示所有以 d 开头的文件中包含 test 的行
grep 'test' aa bb cc # 显示在 aa,bb,cc,文件中匹配 test 的行
grep '[a-z]\{5\}' aa # 显示在 aa 文件中,所有包含至少有 5 个连续小写字符的字符串的行
grep 'w\(es\)t.*\1' aa # 如果 west 被匹配,es 就被存储到内存中,并标记为1,然后搜索任意个字符(.*),这个字符后面紧跟着另外一个es(\1),找到就显示该行。如果egrep或grep -E,就不用“\”号进行转义,直接写成 'w(es)t.*\1' 就可以

为了在不同国家的字符编码中保持一致,POSIX增加了特殊的字符类。

  • POSIX 字符集

    POSIX 字符集是以 [::] 括起来的字符。

POSIX 字符集

字符集 匹配字符
[:alnum:] 文字数字字符,等效于 A-Za-z0-9
[:alpha:] 文字字符
[:blank:] 空格(space)和定位(tab)字符
[:digit:] 数字字符
[:graph:] 非空字符(非空格、控制字符)
[:lower:] 小写字符
[:cntrl:] 控制字符
[:print:] 非空字符(包括空格)
[:punct:] 标点符号
[:space:] 所有空白符(新行、空格、制表符)
[:upper] 大写字符
[:xdigit:] 十六进制数字(0-9,a-f,A-F)
  • 排序符号

    排序符号将多个字符序列视为一个元素。使用 [..] 将字符组合括起来。例如,[.cn.] 表示 cn 字符序列,而单独的 c 或 n 都不行。

  • 等价字符集

    等价字符集表示应视为等值的一族字符,使用 [==] 将字符括起来。例如 e 和 é,在法语的 local 里,[[=e=]] 可能匹配 e/ē/é/ě/è

正则表达式允许将 POSIX 字符集与其他字符集混用,如 [[:alpha:]]!匹配任意一个英文字母或者感叹号(!)。

一个 POSIX 方括号实例

1
2
3
4
5
6
7
8
$ cat test.txt
test grep | test
grep 'w(es)t.*\1'
test test test test
test_12321
123_test
$ grep -E "[[:digit:]]_+" test.txt
test_12321

单个字符

  • 一般字符

    包含文字和数字字符、空白字符和标点符号字符。

  • 转义的 meta 字符

    使用反斜杠 \转义 meta 字符,\\转义反斜杠本身。

  • .(点好)字符

    标识“任一字符”,一般不会单独使用

  • 方括号表达式

    [^...] 取反,即不在方括号里面出现的任意字符;方括号表达式中,所有其他的 meta 字符都会数去其含义。例如 [\.] 匹配反斜杠和点号,而不是匹配句点。

运算符优先级

BRE 的运算优先级

运算符 含义
[…][==][::] 方括号符号
\meta 转义的 meta 字符
[] 方括号表达式
\(\)\n 后向引用表达式
*\{\} 区间表达式和型号表达式
无符号 连续
^$ 锚点

ERE 的运算优先级

运算符 含义
[…][==][::] 方括号符号
\meta 转义的 meta 字符
[] 方括号表达式
() 分组
* + ? {} 重复前置的正则表达式
无符号 连续
^$ 锚点
&#x7C 交替

ERE运算优先级中多出两个运算符,分别是分组和交替

正则表达式的应用

单词的开头结尾匹配

1
2
3
4
$ echo 'this is a word.' | grep "\<word\>" # 匹配单词开头+word+单词结尾
$ echo 'these are words.' | grep "\<word" # 匹配单词开头+word
$ echo 'these are words.' | grep "\<word\>" # 匹配单词开头+word+单词结尾,匹配失败
$ echo 'these are words.' | grep "\<are\>" # 匹配单词开头+are+单词结尾

GNU 支持的额外正则表达式运算符

运算符 含义
\w 匹配任何单词组成字符,等同于 [[:alnum:]_]
\W 匹配任何非单词组成字符,等同于 [^[:alnum:]_]
\<\> 匹配单词的起始与结尾
\b 匹配单词的起始或结尾处所找到的空字符串,这是\<与\>的结合
\B 匹配两个单词组成字符之间的空字符串
\‘\` 分别匹配 emacs 缓冲区的开始与结尾。GNU程序通常将它们视为与^及$同义


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!