4.14. 字符介绍——定位元字符
4.14 字符介绍 —— 定位元字符#
有两个元字符可以让你指定一个字符串出现的上下文 —— 要么在行首或行尾。变音 (^) 元字符是一个表示行首的单字符正则表达式。美元符 ($) 元字符是一个表示行尾的单字符正则表达式。它们通常被称作 “锚”,因为它们将匹配锚定或限制在一个指定的位置。你可以像下面这样打印以一个 tab 开始的行。
^•
这个符号 •
代表了一个字面量的 tab 字符,它通常是不可见的。没有变音元字符(^)。这个表达式将打印包含一个 tab 的任意行,通常,使用 vi 来输入将被 troff 处理的文本时,你不想在行末有空格出现。如果你想找到并移除它们,下面这个正则表达式将匹配有一个或多个空格的行:
□□*$
troff 请求和宏必须输入在一行的开始。它们是前置一个点的双字符字符串。如果 troff request 或宏有一个参数,它通常会跟一个空格。用来搜索这种请求的正则表达式如下:
ˆ\...□
这个正则表达式匹配了 “在行首的一个点,跟着任意的双字符串,然后跟着一个空格。”
你还可以使用这两个定位元字符一起来匹配空行。
^$
你可以使用这个模式,再加上 grep 的计数选项 -c 来对一个文件中的空行进行计数。
$ grep -c '^$' ch04
5
如果你想使用 sed 来删除空行,这个正则表达式是很有用的。
下面这个正则表达式能用来匹配一个空行,即使它包含空格。
^□*$
类似的你还可以匹配一整行:
^.*$
这可能是你想用 sed 做的事情。
在 sed 和 grep 中,变音符 (^) 和美元符 ($) 只有当它们分别出现在一个正则表达式的开头和结尾的时候才是特殊的。因此 “^abc” 这个表达式意味着 “匹配只在行首出现的字母 a,b,c ”,然而 “ab^c” 意味着 ” 匹配 a,b,一个字面量的变音符 (^),然后是 c,不管是在行的任何位置”。同样的,这个规则也适用于 “$”。
awk 则不同,变音符 (^) 和美元符 ($) 总是特殊的,即使可能会写出一个什么都不匹配的正则表达式。简而言之,在 awk 里面,当你想匹配一个字面量的变音符 (^) 或美元符 ($) 的时候,不管它在正则表达式的哪个位置,你需要总是用反斜杠 (\) 来转义它。
短语#
像 grep 这种模式匹配程序,如果它扩展到两行,就不能匹配一个字符串。事实上,确保匹配短语是很困难的。记住,文本文件基本上是结构凌乱的,并且换行符是很随机的。如果你要查询任何单词序列,它们可能出在出现在一行,但也可能分隔在两行上。
你可以写一系列的正则表达式来捕获一个短语:
Almond Joy
Almond$
ˆJoy
但是这个并不完美,因为不管下一行是不是以 Joy 开头,第二个正则表达式将匹配行尾的 Almond 的。类似的问题也存在于第三个正则表达式。
后面,当我们学 sed 的时候,你将会学到如何在多行上匹配模式,还将看到一个 shell 脚本结合 sed 来使得这个功能普遍可用。