添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

你有没有想过,在 shell 命令行 中的 *,? 正则表达式 中的 *,? 是否一样?

自打好多年前接触 DOS,就知道了 * ? 这两个 通配符 (Wildcard),象 dir *.* 这样的命令也不知道敲了多少遍。

后来,开始用 Windows 3.1 这样的图形界面操作系统,命令行就就得越来越少了。

再后来,开始学习正则表达式,又开始接触 * ? 这样的东西。在正则中它们被称为 元字符 (Meta Character)。

再再后来,开始使用 Linux,于是又开始使用命令行,又开始在命令行中使用 * ?

最终,这两种形同且意相似,实质上完全不同但又有神秘联系的东西成功地交织一起,把我彻底搞凌乱了。

不过,搞清楚它们的不同之处,就不会凌乱了。

Shell 命令中的通配符

在操作系统的 Shell 命令中, * ? 这样的通配符和其它字符一起组合成表达式,用于匹配符合条件的文件名。

* : 匹配任意长度的字符串。这个字符串的长度可以是 0 ,可以是 1 ,可以是 任意 数字

? : 匹配任意 一个 字符。

例如, a?c.* 可以匹配 abc.o axc.docs azc.htm 这样的文件名。

通配符在 DOS/Windows 和 Linux 中的差别

在 Linux 中, ? 只能匹配一个字符。但在 DOS/Windows 中,如果 ? 处于末尾或者 . 的前面,它也可以匹配零个字符。例如在 DOS/Windows 中, abc?.* 可以匹配 abc.html abcd.md 这样的文件名。

在 DOS/Windows 中, ? 不能匹配文件名中的 . 。比如 abc?md 不能匹配 abc.md

在 Linux 中,如果 . 在文件名的开头,不能用 * ? 来匹配。

另外,以 . 开头的文件名在 Linux 中很普遍,但在 DOS/Windows 中就很另类,会产生些问题。不提了,不提了,都是坑。

正则表达式中的元字符

在正则表达式中, * ? 这样的元字符、其它元字符以及普通字符组合在一起形成一个 Pattern ,用于匹配字符串。比如在文本文件中找出所有包含某个字符串的行。

* : 匹配 前面 的表达式零次或多次。

? : 匹配 前面 的表达式零次或一次。

表达式可以是一个字符,也可以是 ( ) 中的字符序列。

例如, ab*c 可以匹配 ac abcc acef dabbbbbcf 这样的字符串

两者的区别

区别一:作用对象不同

这一点前面已经说过了:一个用于 Shell 命令中匹配文件名,另一个用于文本处理中匹配相应的字符串。

区别二:工作方式不同

在命令行中,通配符是占位符,可以独立使用,跟前面的字符没关系。比如 abc* ,表示一个字符串以 abc 开始,然后跟 0 个或多个任意字符。

在正则表达式中, * ? 是对前面的表达式进行匹配次数限制,不能独立使用的。比如 abc* ,表示字符串中包含 ab ,后面跟上 0 个或多个 c 。这个表达式可以匹配 ab , abc , abcc , abcccd 这样的字符串。这里的 * 作用在它前面的 c 上(如果想作用于它前面的 abc ,要写成 (abc)* )。

举两个例子:

用于命令行文件名匹配时,可以匹配只有一个字符的名字: t x 等;

用于正则表达式中字符串匹配时,它是无效表达式。

两者之间还是有些联系的,纯粹靠区别还不足以把人搞凌乱。

通配符也可以用在字符串匹配上

它们也可用在一般的字符串查找上。比如在查询系统中,你可以使用通配符来实现简单的模糊查询。这时它们的工作方式跟命令行是一致的。许多系统都提供了基于通配符的简单查询和基于正则表达式的复杂查询。

在我们经常使用的 SQL 中, % _ 这两个字符就作为通配符,跟 LIKE 操作符一起,用于字符串匹配。但 SQL 也提供了基于正则的字符串匹配操作。

在正在表达式中也有通配符

正则的元字符 . 有时也被称为通配符,因为它可以匹配任意一个字符。

通配符有等价的正则表达式

若不考虑 ? 可以匹配零个字符这种情况,通配符和正则有下面的关系:

通配符等效的正则表达式

通配符、正则表达式可以放在一起使用

Linux grep 命令就是一个很好的例子。这个命令的参数可以同时包括通配符和正则表达式,大家自己去体会吧。真个是:联袂而至,没有最凌乱,只有更凌乱。