通配符和正则表达式在命令行以及文本处理方面非常有用。当在命令行工作时,使用通配符扩展文件名;
当使用 grep, awk, sed 等处理文本时,使用正在表达式匹配文本。 这里做一下总结:
通配符用于路径名扩展,而正则表达式用于文本匹配。
通配符
很久以前,在 Unix V6 中,有一个程序 /etc/glob 可以展开 通配符模式(wildcard pattern)。
后来这就成了一个 shell 内建的特性。而且还有一个 glob 库供用户编程使用。
如果一个字符串包含了字符 ?,* 或者 [ 中的一个,那么它就是一个通配符模式。通配符扩展
将一个通配符模式展开为一系列的路径名。匹配是这样定义的:
?: 匹配任意单个字符*: 匹配任何字符串包含空串
字符类
如果由方括号括起来的表达式 [...] 中的第一个字符不是感叹号 !,那么该表达式匹配一个字符。
该字符可以是方括号中的任何一个字符。 方括号内的字串不能为空; 因此 ] 可以位于 方括号中,
但是它必须是第一个字符。 例如,模式:[][!] 匹配三个字符 ], [ 和 ! 之一。
命名字符类
POSIX 定义了以下命名字符类:
[:alnum:] [:alpha:] [:blank:] [:cntrl:]
[:digit:] [:graph:] [:lower:] [:print:]
[:punct:] [:space:] [:upper:] [:xdigit:]
所以,可以使用 [[:lower:]] 代替 [a-z]。
范围
有一个特别的规则:由连字符 - 分隔的两个字符代表一个范围。 因此模式 [A-Fa-f0-9] 和
模式 [ABCDEFabcdef0123456789] 等效。如果要想表示连字符本身,可以将它放在方括号的最前面
或者最后面。因此, []-] 匹配字符 ] 或者 - ,
取反
可以对字符类取反,让字符类匹配除了方括号内的字符以外的任何一个字符。只需要在 开方括号 [
后面加上一个感叹号 !。例如: [!]a-] 匹配任何一个字符,除了 ], a 和 -。
转义
可以通过在字符 '?','*','[' 前面加上反斜杠来去除其特殊含义。然而,当这些特殊字符位于
方括号内部的时候,它们代表自己,没有特殊含义。因此,模式 []?*\] 匹配四个字符:],
?, * 和 \ 中的一个。
路径名
通配符扩展分别应用于路径名的每个部分。路径名中的 / 不能由 ? 或者 * 匹配,也不能被一个
范围匹配。范围不能显式地包含字符 / ;否则会导致语法错误。
如果一个文件名以 . 开头,该字符必须被显式匹配。因此: rm * 不会删除 .profile,
tar c * 不会打包所有的文件; 使用 tar c . 是一个更好的选择。
正则表达式
根据 POSIX.2 的定义,有两种格式的正则表达式:扩展正则表达式 和 基本正则表达式。基本 正则表达式当前仍然存在主要是为了保持向后兼容。
定义
扩展正则表达式 是由一个或者多个非空的 branch 由管道符号 | 分隔而成的。只要匹配其中一个
branch 即匹配该正则表达式。
一个 branch 是由一个或者多个 pieces 连接在一起的。
一个 piece 是一个 atom,后跟一个 *, +, ? 或者 bound。
一个 atom 可以是:
- 扩在小括号
()中的正则表达式 - 一对空小括号
(),可以匹配空串 - 一个方括号表达式
[abc...],匹配方括号内的任意一个字符 .,英文句点,匹配任何一个字符^,匹配行首$,匹配行尾- 反斜杠后跟以下字符:
^.[$()|*+?{\,匹配该字符 - 反斜杠后跟任何其他字符,匹配那个字符
- 单个字符,匹配该字符
一个 bound 形如:{start,end},其中:
start和end是无符号整数,必须位于 0 和 255(包含)之间,和end是可选的。- 如果有两个整数,第一个不能大于第二个。
如果大括号 { 后跟一个非数字字符,那么大括号就是一个普通字符,不代表 bound 的开始。正则表
达式不能以反斜杠 \ 结尾。
匹配次数
- 后跟
*的 atom 匹配该 atom 0 次或者多次 - 后跟
+的 atom 匹配该 atom 1 次或者多次 - 后跟
?的 atom 匹配该 atom 0 次或者 1 次 - 后跟
{start}的 atom 准确匹配该 atom start 次 - 后跟
{start,}的 atom 匹配该 atom start 或者更多次。 - 后跟
{start,end}的 atom 匹配该 atom start 到 end(包含)次,包含。
方括号表达式
方括号表达式是括在方括号内的一系列字符。它匹配方括号内的任意一个字符。
- 要将
]放进方括号中,必须将之作为方括号内的第一个字符 - 要将
-放进方括号中,必须将之作为方括号内的第一个或者最后一个字符
取反
如果方括号内的字符以 ^ 开头,它匹配任何不在该字符列表中的字符。取反的语法,跟通配符
不同,通配符通过感叹号 ! 在方括号内取反。
范围
在方括号内,可以表示范围。表示范围的语法和通配符相同。如果两个字符以连字符 - 分隔,
那么就代表一个范围。两个范围共享同一端点是非法的,例如:a-c-e。正则表达式的命名字符类和
通配符中使用的命名字符类相同。
基本正则表达式
基本正则表达式有几个方面不一样。
|+?是普通字符,在基本正则表达式中没有和它们对等的功能。- bound 由
\{和\}定义,{和}是普通字符 - 用于子表达式的小括号是
\(和\),(和)是普通字符
参考
man 7 globman 7 regex