# 正则表达式 `正则表达式`是表达文本模式的方法。 - `.`:匹配任何单个字符。 - `?`:上一项是可选的,最多匹配一次。 - `*`:前一项将被匹配零次或多次。 - `+`:前一项将被匹配一次或多次。 - `{N}`:上一项完全匹配N次。 - `{N,}`:前一项匹配N次或多次。 - `{N,M}`:前一项至少匹配N次,但不超过M次。 - `--`:表示范围,如果它不是列表中的第一个或最后一个,也不是列表中某个范围的终点。 - `^`:匹配行首的空字符串;也代表不在列表范围内的字符。 - `$`:匹配行尾的空字符串。 - `\b`:匹配单词边缘的空字符串。 - `\B`:匹配空字符串,前提是它不在单词的边缘。 - `\<`:匹配单词开头的空字符串。 - `\>`:匹配单词末尾的空字符串。 ## 元字符 `元字符`是表示特殊函数的字符,包括以下这些`^ $ . [ ] { } - ? * + ( ) | \\`。除了元字符,其他字符在正则表达式中,都表示原来的含义。 - `.` 匹配任意字符,但不含空字符 - `^` 匹配文本行开头 - `$` 匹配文本行结尾 ```bash $ grep -h '.zip' dirlist*.txt ``` 上面命令在文件中查找包含正则表达式“.zip”的文本行。注意,上面命令不会匹配`zip`程序,因为`zip`只有三个字符,而`.zip`要求四个字符。 ```bash $ grep -h '^zip' dirlist*.txt $ grep -h 'zip$' dirlist*.txt ``` 上面命令分别在文件列表中搜索行首,行尾以及行首和行尾同时包含字符串“zip”(例如,zip 独占一行)的匹配行。 注意正则表达式‘^$’(行首和行尾之间没有字符)会匹配空行。 ## 方括号 方括号之中的字符,表示可以任意匹配其中的一个。 ```bash $ grep -h '[bg]zip' dirlist*.txt ``` 上面命令匹配包含字符串“bzip”或者“gzip”的任意行。 注意,元字符放入方括号之中,会失去其特殊含义。但有两种情况除外,`^`在方括号的开头,表示否定,否则只是一个普通字符,表示原义。 ```bash $ grep -h '[^bg]zip' dirlist*.txt ``` 上面命令匹配不以`b`或`g`开头的`zip`字符串。注意,上面命令不会匹配`zip`,因为一个否定的字符集仍然要求存在一个字符。 `-`在方括号之中表示一个字符区域。 ```bash $ grep -h '^[A-Z]' dirlist*.txt ``` 上面命令匹配所有以大写字母开头的文本行。类似的,`^[A-Za-z0-9]`表示以大写字母、小写字母、数字开头的文本行。 注意,连字号如果不构成一个字符区域,则表示其本来的含义。 ```bash $ grep -h '[-AZ]' dirlist*.txt ``` 上面命令匹配包含一个连字符,或一个大写字母“A”,或一个大写字母“Z”的文件名。 ## 预定义字符类 由于`locale`设置不同,Shell展开正则表达式`[A-Z]`时,可能不是解释为所有大写字母,而是解释为包括所有字母的字典顺序。 ```bash $ ls /usr/sbin/[A-Z]* ``` 上面命令在某些发行版里面,会返回所有大写字母或小写字母开头的文件。 为了避免这个问题,可以使用正则表达式的预定义字符类。 - `[:alnum:]` 字母数字字符。在 ASCII 中,等价于:`[A-Za-z0-9]` - `[:word:]` 与`[:alnum:]`相同, 但增加了下划线字符。 - `[:alpha:]` 字母字符。在 ASCII 中,等价于`[A-Za-z]` - `[:blank:]` 包含空格和 tab 字符。 - `[:cntrl:]` ASCII 的控制码。包含了0到31,和127的 ASCII 字符。 - `[:digit:]` 数字0到9 - `[:graph:]` 可视字符。在 ASCII 中,它包含33到126的字符。 - `[:lower:]` 小写字母。 - `[:punct:]` 标点符号字符。 - `[:print:]` 可打印的字符。等于`[:graph:]`中的所有字符,再加上空格字符。 - `[:space:]` 空白字符,包括空格,tab,回车,换行,vertical tab, 和 form feed.在 ASCII 中, 等价于`[ \t\r\n\v\f]` - `[:upper:]` 大写字母。 - `[:xdigit:]` 用来表示十六进制数字的字符。在 ASCII 中,等价于`[0-9A-Fa-f]` ```bash $ ls /usr/sbin/[[:upper:]]* ``` 上面命令返回所有大写字母开头的文件名。 ## 选择 `|`表示匹配一系列字符串之中的一个。注意与方括号区分,方括号表示匹配一系列字符之中的一个。 ```bash $ echo "AAA" | grep -E 'AAA|BBB' AAA $ echo "BBB" | grep -E 'AAA|BBB' BBB $ echo "CCC" | grep -E 'AAA|BBB' $ ``` 上面代码中,`AAA|BBB`表示匹配字符串`AAA`或者是字符串`BBB`。`grep`程序使用`-E`参数,表示按照正则表达式规则匹配。并且,这个正则表达式放在单引号之中,为的是阻止Shell把`|`解释为管道操作符。 `|`可以多个连用,也可以与其他正则规则结合使用。 ```bash $ echo "AAA" | grep -E 'AAA|BBB|CCC' $ grep -Eh '^(bz|gz|zip)' dirlist*.txt ``` ## 量词操作符 量词操作符表示一个元素被匹配的次数。 - `?` 匹配前面的元素出现0次或1次 - `*` 匹配前面的元素出现0次或多次 - `+` 匹配前面的元素出现1次或多次 - `{n}` 匹配前面的元素出现了`n`次 - `{n,m}` 匹配前面的元素它至少出现了`n`次,但是不多于`m`次 - `{n,}` 匹配前面的元素至少出现了`n`次 - `{,m}` 匹配前面的元素,如果它出现的次数不多于 m 次。