还是来自ABS 最新版的摘录,这次是第十七章,关于正规表达式。以下是摘录和翻译。
一个表达式是一串字符 这些字符表达的意思超出了字面意思,我们称之为元字符(metacharacters).
正规表达式是一个字符或者元字符集,用来匹配或者模式(patterns)。 一个正规表达式包含以下一个或者多个情形:
- 一个字符集. 这些字符保留他们的字面意义。 最简单的正规表达式类型就是这种仅由这些字符组成,而没有元字符
- 锚(anchor). 锚 指定正规表达式匹配的一行文本的位置。 比如, \, 和 $ 就都成为锚。
- 修饰符(Modifiers). 它扩展或者缩小(修改) 正规表达式匹配的文本范围。修饰符包括星号(*),括号({,(,<)和反斜杠(\)
正规表达式主要用来文本匹配和字符串操作。一个正规表达式匹配单个字符或者字符集–字符串或者其一部分。
- 星号 * – 匹配任意多个字符包括0个字符 “1133*” 匹配 11 + 一个或者多个3: 113, 1133, 1133333, 等等。
- 点 . – 匹配任意一个字符,除了新行(newline)。 “13.” 匹配 13 + 任意一个字符(包括空格): 1133, 11333, 但是不包括13 。
- 脱字符 \^ – 匹配一行的开始,但是也依赖上下文,有时表示一个字符集的反面,即不匹配这个字符集。
- 美元符 $ – 匹配一行的结尾。 “XXX$” 匹配以 XXX 结尾的行。 “\$”匹配空白行。
中括号 […] – 在正规表达式里匹配一个封闭字符集的单个字符。 “[xyz]” 匹配x, y, 或 z中的任何一个字符 “[c-n]” 匹配c 到 n范围字符集中的任何一个 “[B-Pk-y]” 匹配任何B到P和k到y的字符.
“[a-z0-9]” 匹配任意一个小写字母或者数字。 “[\b-d]” 匹配任意字符,除了 b 到 d 的字符集之外。
在这里实例中 \^ 除正规表达式的负面或者相反面的意思(类似shell里的 ! 符号的作用)。 将多个中括号表达式合在一起,通常用来匹配单词模式。”[Yy][Ee][Ss]” 匹配 yes, Yes, YES,yEs,等等。
“[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]” 匹配任意社会安全码。- 反斜杠 \ – 转义 特殊字符,使得该字符按照字面意思来解释(因此,它就不再是特殊字符了)。 “\$” 取回”$”符号本身的意思,而不是正规表达式里表示行尾的意思。 同样的, “\” 表示”" 符号的本意。
- 转义 “尖括号” \<…\> – 标记单词边界。 尖括号必须转义,否则仅仅表示本意。 “\<the\>” 匹配单词 “the,” 但是不匹配单词 “them,” “there,” “other,” ,等等。
额外的一些元字符添加到基本集合里用在 egrep, awk, 和 Perl 里。
- 问号 ? – 匹配0个或者一个正规表达式之前的字符,通常用来匹配单个字符。
加号 + – 匹配正规表达式之前的一个或者多个字符,和 * 类似,但是不匹配0个字符。
# GNU versions of sed and awk can use "+", # but it needs to be escaped. echo a111b | sed -ne '/a1\+b/p' echo a111b | grep 'a1\+b' echo a111b | gawk '/a1+b/' # All of above are equivalent. # Thanks, S.C.转义的 “大括号/花括号” \{ \} – 表示正规表达式匹配的数量。和尖括号一样,必须转义,否则只表示其本意。这个表达方式不是正规表达式集合的一部分。
“[0-9]\{5\}” 准确匹配5个字符。 大括号在”经典” (非POSIX兼容)版的 awk里并不作为正规表达式生效。但是,GNU 扩展版本的 awk, gawk 提供了 –re-interval 可选参数使其有效(不需要转义)。bash$ echo 2222 | gawk --re-interval '/2{3}/' 2222Perl 和一些 egrep 版本并不要求转义大括号。
圆括号 ( ) – 封装一组正规表达式。用expr提取子串或者接管道(“|”)操作时,这个表达式就显得有用。
| “或” 表示匹配可选字符集中的某一个。
bash$ egrep 're(a|e)d' misc.txt People who read seem to be better informed than those who do not. The clarinet produces sound by the vibration of its reed.POSIX 字符类. [:class:] 指定一个字符范围用来匹配的一种替代方案
- [:alnum:] 匹配字母或者数字字符。等价于 A-Za-z0-9.
- [:alpha:] 匹配字母。 等价于 A-Za-z.
- [:blank:] 匹配空格或者tab健。
- [:cntrl:] 匹配控制字符。
- [:digit:] 匹配数字(十进制)。等价于 0-9.
- [:graph:] (图形打印字符)。匹配ASCII码在33 - 126 范围的字符。和下面提到的 [:print:] 相同,但是除空格字符除外。
- [:lower:]匹配小写字母。 等价于 a-z.
- [:print:] (可打印字符)。 匹配 ASCII 码在 32 - 126 范围的字符。和上面提到的 [:graph:] 相同,不过还要加上空格字符。
- [:space:] 匹配空白字符(空格和水平制表符)。
- [:upper:] 匹配大些字母. 等价于 A-Z。
[:xdigit:] 匹配十六进制数字。等价于 0-9A-Fa-f.
POSIX 字符类通常需要引号或者双括号([[ ]])。
bash$ grep [[:digit:]] test.file abc=723 # ... if [[ $arow =~ [[:digit:]] ]] # Numerical input? then # POSIX char class if [[ $acol =~ [[:alpha:]] ]] # Number followed by a letter? Illegal! # ... # From ktour.sh example script.以上字符类甚至可以当做通配符,用做有限的扩展,比如。
bash$ ls -l ?[[:digit:]][[:digit:]]? -rw-rw-r-- 1 bozo bozo 0 Aug 21 14:47 a33b
在筛选,文件转换或者I/0流操作中,Sed, awk, 和 Perl, 带一个正规表达的参数在脚本里用来过滤(filter)。