Linux学习笔记(四):正则表达式
一、正则表达式
正则表达式是一种符号表示法,用于识别文本模式
grep命令
grep(global regular expression print)用于查找文件里符合条件的字符串,很显然可以搭配正则表达式
grep [options] regex [file...] //grep命令的格式,在参数选项之后是一个regex(正则表达式)
-i 忽略大小写(–ignore-case)
-l 查找匹配项的文件名,不是文本行本身(–files-with-matches)
-L 跟-l 参数相反,查找不包含匹配项的文件名(–files-without-match)
grep -i you 1.txt //虽然不太被注意,但是grep命令是利用正则表达式来达到查找的目的,
这里的待匹配字符“you”是原义字符,仅仅匹配字符本身,加上参数-i用于忽略待匹配的字符的大小写限制
二、原义字符、元字符
原义字符,用于匹配本身。 除了原义字符之外,正则表达式中的元字符,被用来指定更复杂的匹配项。
^ $ . [ ] { } - ? * + ( ) | \
除了上面的几个元字符之外,其它所有字符都被认为是原义字符。(允许元字符被转义为原义字符,而不是被解释为元字符)
当在命令行中传递包含元字符的正则表达式的时候,把元字符用引号引起
任意字符
圆点字符,被用来匹配任意字符
grep -h ".oov." /usr/share/dict/words //-h参数不显示该行所属的文件名称。在Linux自带的字典中查找
原点字符会匹配在此位置的任意一个字符,正则表达式中包含的圆点字符加上原义字符等于匹配的字符长度。
文件扩展名中的圆点符号也会被看作是任意字符被匹配
锚点
插入符号和美元符号被看作是锚点。正则表达式只有在文本行的开头或末尾被找到时,才算发生一次匹配。
grep -h '^yo' /usr/share/dict/words //开头匹配
grep -h 'yo$' /usr/share/dict/words //结尾匹配
grep -h '^you$' /usr/share/dict/words //完全匹配
正则表达式‘^$’(行首和行尾之间没有字符)会匹配空行
中括号表达式
中括号表达式,能够指定字符集合来被匹配(包含元字符)
grep -h '[you]ou' /usr/share/dict/words
一个字符集合可能包含任意多个字符,大部分元字符也会失去特殊含义 (插入字符,其被用来表示否定;连字符字符,用来表示一个字符区域)
在正则表示式中的第一个字符是一个插入字符,则剩余的字符被看作是不会在给定的字符位置出现的字符集合
grep -h '[^you]oou' /usr/share/dict/words
一个否定的字符集仍然在给定位置要求一个字符, 但是这个字符必须不是否定字符集的成员
grep -h '^[0123456789]' filename //匹配系列字符,可以使用-符号来进行
grep -h '^[0-9]' filename //任意字符的区域都能使用-这种方式来表达
grep -h '^[-AZ]' filename //连字符放在正则表达式的第一个,本例中用于匹配大写字母A或者大写字母Z或者一个连字符
三、POSIX字符集
POSIX 标准介绍了一个概念locale (可以被调整,用于选择所需的字符集)
-
ASCII 字符,前32个字符 (数字0-31)都是控制码(如 tabs,backspaces和Enter等)
-
随后的32个字符 (数字32-63) 包含可打印的字符, 包括大多数的标点符号和数字0到9。
-
之后的32个字符 (数字64-95) 包含大写字符和一些更多的标点符号。
-
最后的31个字符 (数字96-127) 包含小写字母和更多的标点符号。
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
输入echo $LANG
可以查看当前系统的语言设置
POSIX 标准包含了大量的字符集,提供了有用的字符区域。
字符集 | 说明 |
---|---|
[:alnum:] | 字母数字字符。在 ASCII 中,等价于:[A-Za-z0-9] |
[:word:] | 与[:alnum:]相同, 增加了下划线字符。 |
[:alpha:] | 字母字符。在 ASCII 中,等价于:[A-Za-z] |
[:blank:] | 包含空格和 tab 字符。 |
[:cntrl:] | ASCII 的控制码。包含了0到31,和127的 ASCII 字符。 |
[:digit:] | 数字0到9 |
[:graph:] | 可视字符。在 ASCII 中,它包含33到126的字符。 |
[:lower:] | 小写字母。 |
[:punct:] | 标点符号字符。在 ASCII 中,等价于: |
[:print:] | 可打印的字符。在[:graph:]中的所有字符,再加上空格字符。 |
[:space:] | 空白字符,包括空格,tab,回车,换行,vertical tab, 和 form feed.在 ASCII 中, 等价于:[ \t\r\n\v\f] |
[:upper:] | 大写字母。 |
[:xdigit:] | 用来表示十六进制数字的字符。在 ASCII 中,等价于:[0-9A-Fa-f] |
ls filename/[[:upper:]]* //查找该路径下含有大写字母的文件
该例子并不是正则表达式,但是POSIX规范的字符集适用于正则表达式
环境变量 LANG
环境变量LANG用于设置POSIX 规范的字符集
可以通过修改LANG的值
LANG=POSIX
来使用传统的unix,还可以通过添加语句export LANG=POSIX
到.bashrc 文件中,使更改永久有效。
四、扩展的正则表达式
POSIX 把正则表达式的实现分成了两类: 基本正则表达式(BRE) 和扩展的正则表达式(ERE)
关于BRE和ERE的区别,体现在对于元字符的识别上
BRE:^ $ . [ ] *
ERE:( ) { } ? + |
在 BRE 中,字符“(”,“)”,“{”,和 “}”用反斜杠转义后,被看作是元字符, 而在ERE 中,在任意元字符之前加上反斜杠会导致其被看作是一个文本字符。
Alternation(交替)
alternation从一系列字符串或者其它的正则表达式中选择匹配项
echo "CAHNWILL" | grep -E 'A|C|L' //-E选项,这是一个扩展的特性,用于查找其中一个
grep -Eh '^(Y|O|U)' filename //还可以将alternation与其它正则表达式相结合,使用()来分离alternation
grep -Eh '^Y|O|U' filename //如果去掉括号,就会变成查找开头是Y,或是O、U的文件名
限定符
ERE支持几种方法,来指定一个元素被匹配的次数
?:匹配零个或一个元素,问号前面的元素可有可无
^\(?[0-9][0-9][0-9]\)? [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]$ //使用反斜杠来让元字符()变成原义字符,之后加上问号表示可以匹配零次或者一次
*:匹配零个或多个元素
[[:upper:]][[:upper:][:lower:] ]*. //用*表示出现的字符可以出现多次或者不出现
+:匹配一个或多个元素
^([[:alpha:]]+ ?)+$ //+前面的字符必须出现过一次,?前面一个空格表示可有可不有,结尾的$锚点即结尾必须跟正则表达式相匹配。
{ }:匹配特定个数的元素(匹配的最小和最大数目)
限定符 | 说明 |
---|---|
{n} | 匹配前面的元素,出现了 n 次 |
{n,m} | 匹配前面的元素,至少出现了 n 次,但是不多于 m 次 |
{n,} | 匹配前面的元素,出现了 n 次或多于 n 次 |
{,m} | 匹配前面的元素,出现小于等于 m 次 |
^\(?[0-9][0-9][0-9]\)? [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]$
修改命令
^\(?[0-9]{3}\)? [0-9]{3}-[0-9]{4}$ //通过{}来化简匹配
反引用
``引用一些函数、命令输出等,执行时会将反引号中的内容当作一个命令执行
ls -l `cat /etc/shells` //将``里的内容先进行执行,结果作为ls命令的输入
五、关于正则表达式
本篇是对于正则表达式的简单介绍,具体的在Linux系统中的用法需要配合一些文本处理的强大的命令(grep、awk、find……)来发挥出作用,这将会在下一篇详细介绍。
正则表达式的应用也不止限于Linux系统,几乎所有语言中都可以使用,它强大的的灵活性、逻辑性和功能性可以迅速地用极简单的方式达到字符串的复杂控制。
之后对于正则表达式的学习也不会仅限于这一篇文章,正则表达式的学习需要一遍一遍地去动手操作,上手不难,但是要成为一个精通正则表达式的正则带师,还需要很长一段路要走。
本篇参考《The Linux Command Line》、Linux官方文档等