通配符和正则表达式在命令行以及文本处理方面非常有用。当在命令行工作时,使用通配符扩展文件名;
当使用 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 glob
man 7 regex