深色模式
正则表达式 - 基础正则
参考:《Linux技巧:详解正则表达式和通配符的用法和它们的区别》
正则表达式提供了一个从字符串中选取特定子字符串的机制,分为基本正则表达式(BRE)、扩展正则表达式(ERE)两种形式。
正则表达式的组成:
- 普通字符
- 特殊字符
- 方括号表达式
- 子表达式
特殊字符
POSIX 标准定义的基本正则表达式只支持.
[
\
*
^
$
这6个特殊字符,而且这些字符要在特定上下文环境中才具有特殊含义。
.
匹配任意一个字符,但不包括空字符 NUL。对于那些要求以换行符结尾的工具来说,点号
.
匹配不到行末的换行符。在
[]
之外才有特殊含义。[
[
与]
组成方括号表达式,注意]
不是特殊字符。在
[]
之外才有特殊含义。\
对特殊字符进行转义,表示特殊字符自身。
在
[]
之外才有特殊含义。*
匹配0或连续多个上一个BRE表达式。
特殊含义生效条件:
*
出现在方括号[]
之外。*
不在BRE的开头,也不在BRE开头的^
后面。*
不在子表达式的\(
后面,也不在\(^
的后面。
^
特殊含义一:匹配字符串的开头。
^
在[]之外生效。特殊含义二:不匹配**
[]
**内所有字符。^
是[]
之内第一个字符时生效。$
匹配字符串末尾。
$
是BRE的最后一个字符时生效。
方括号表达式
普通方括号表达式
方括号 []
表达式(bracket expression)用于匹配 []
内字符集合的任意一个字符,所给的字符集合不能为空。
例:
sh
grep [] myfile # 语法错误!!!
grep [\] myfile # 匹配'\'
grep []] myfile # 匹配']'
grep [[] myfile # 匹配'['
grep [ myfile # 语法错误!!!
grep ] myfile # 匹配']'
grep [^ab] myfile # 匹配除'a','b'以外任意一个字符
grep [a^b] myfile # 匹配'a','^','b'三个字符其中一个
字符类表达式
字符类表达式(character class expression)用于指定某一类字符集合。
POSIX 标准定义了 12 个字符类型,说明如下:
字符类别 | 含义 |
---|---|
[:alnum:] | 字母字符和数字字符 (可以匹配中文字符) |
[:alpha:] | 字母字符 (可以匹配中文字符) |
[:blank:] | 空白字符,特指空格和 tab 字符,不包含换行符 |
[:cntrl:] | 控制字符 |
[:digit:] | 数字字符 |
[:graph:] | 图形字符,包括字母、数字、标点符号,不包括空格 |
[:lower:] | 小写字符 (不能匹配中文字符) |
[:print:] | 可打印字符,包括字母、数字、标点符号、和空格 |
[:punct:] | 标点符号,也包括运算符、各种括号等 |
[:space:] | 所有空白字符 (空格,制表符,换行符,回车符) |
[:upper:] | 大写字符 (不能匹配中文字符) |
[:xdigit:] | 十六进制数字 (0-9,a-f,A-F) |
例:
Bash
echo 'hello911' | grep [[:digit:]] #匹配911三个数字
范围表达式
范围表达式(range expression)表示两个字符之间的所有字符集合,包括这两个字符本身。这两个字符通过连字符-
隔开。注意:如果要匹配连字符-
,需要把连字符放到开头或末尾。
例:
Bash
echo 'Hello' | grep [A-Z] #匹配'H'
echo 'Hello-Wolrd' | grep [-AZ] #匹配'-'
echo 'Hello' | grep [Z-A] #范围错误!!!
子表达式
子表达式(subexpression)是使用 \(
和 \)
括起来的表达式,被括起来的字符集合保持原有的含义。
例如在子表达式\( \)
内,字符a
还是匹配它自身,点号.
表示匹配任意一个字符,可以用反斜线\
来转义,可以用方括号[]
表达式来匹配字符集合中的任意一个字符,等等。
比较特别的是^
字符。当^
出现在子表达式开头、紧跟在\(
之后时,是用于匹配字符串开头,还是匹配^
字符自身,是可选行为。POSIX 标准说是取决于具体的实现,也就是由工具自身决定。这可能会带来移植性问题。
子表达式可以嵌套使用。
反向引用表达式
反向引用表达式(back-reference expression)用于反向引用前面的子表达式,其写法是\n
,n 必须是 1 到 9 之间的数字,包括 1 和 9。\n
会匹配从整个表达式开头数起的第 n 个子表达式对应的内容,最多只能匹配到第 9 个子表达式。但还是可以提供 10 个、以及更多的子表达式,只是不能通过反向引用表达式来引用到。
反向引用可以用来重复利用前面的子表达式。
区间表达式
区间表达式(interval expression)指定在它前面的一个表达式要匹配多少次,其写法是\{m\}
、\{m,\}
、或者\{m,n\}
,m、n 的值要满足 0 <= m <= n 这个范围。
{m}
\{m\}
指定要精确匹配 m 个前一个表达式。\{m,\}
指定至少匹配 m 个前一个表达式。\{m,n\}
指定至少匹配 m 个前一个表达式,最多匹配 n 个前一个表达式。
例:
Bash
grep 'a\{3\}' myfile #匹配'aaa'
grep 'a\{3,\}' myfile #匹配'aaa','aaaa','aaaaa'等
grep 'a\{3,4\}' myfile #匹配'aaa','aaaa'
grep '\(ab\)\{2\}' myfile #匹配'abab'