一、前言
在我们初学Liunx时,就会遇到一拦路虎,那就是“正则表达式”。原因在于其结构的复杂性和逻辑性较强,需大量的练习才能将其掌握。故本文主要整理总结了正则表达式在grep(和egrep)中的基本用法,使大家对正则表达式有个整体的认识。
二、名词解释
正则表达式:
元字符:
-
正则表达式中具有特殊意义的专用字符(类似于C语言中的关键字);
不表示字符本身的意义,而是用于额外的功能性描述;
三、分类
四、基本正则表达式(grep)
基本正则表达式的元字符:
字符匹配:
.:任意单个字符 [ ]:指定范围内的任意单个字符 [^]:指定范围外的任意单个字符
其中[ ]中字符范围如下:
[a-z]:匹配单个小写字母 [A-Z]:匹配单个大写字母 [0-9]:匹配单个数字 [[:upper:]]:匹配单个大写字母 [[:lower:]]:匹配单个小写字母 [[:alpha:]]:匹配单个字母(不分大小写) [[:digit:]]:匹配单个数字 [[:alnum:]]:匹配单个字母或数字 [[:space:]]:匹配单个空白(包括空格,tab等) [[:punct:]]:匹配单个标点符号 [^]:指定范围外的任意单个字符
*:任意次(.*匹配任意长度的任意字符) \?:0次或1次 \{m\}:匹配m次 \{m,n\}:匹配m~n次 \{m,\}:匹配至少m次 \{0,n\}:匹配至多n次
位置锚定:用于指定字符出现的位置
^:锚定行首 $:锚定行尾(^$表示空白行) \<:锚定词首,也可表示为\b \>:锚定词尾,也可表示为\b
分组:又可称为子模式
\( \):如\(ab\)*xy
引用:
\1:后向引用,引用前面的第一个左括号以及与之对应的右括号中的模式所匹配到的内容
五、扩展正则表达式(egrep)
“扩展正则表达式”较之“基本正则表达式”,元字符更加精简,不再需要反斜杠(\)转义,且增加了+,|等元字符,如下:
字符匹配:
.:任意单个字符 [ ]:指定范围内的任意单个字符 [^]:指定范围外的任意单个字符
次数匹配:
*:匹配前面的字符任意次 ?:匹配0或1次 +:匹配至少1次(新增) {m}:匹配m次 {m,n}:匹配m~n次 {m,}:匹配至少m次 {0,n}:匹配至多n次
位置锚定:
^:行首 $:行尾 \<,\b:词首 \>,\b:词尾
分组:
( ):分组 |:或 (新增)
引用:
\1:后向引用,引用前面的第一个左括号以及与之对应的右括号中的模式所匹配到的内容
六、实例
Question1:
显示/etc/rc.d/rc.sysinit文件中以#开头,后面跟至少一个空白字符,而后又有至少一个非空白字符的行
Answer1:
grep "^#[[:space:]]\{1,\}[^[:space:]]\{1,\}" /etc/rc.d/rc.sysinit
Question2:
显示/boot/grub/grub.conf中以至少一个空白字符开头的行
Answer2:
grep "^[[:space:]]\{1,\}" /boot/grub/grub.conf
Question3:
找出ifconfig命令结果中的1到255之间的整数
Answer3:
ifconfig | egrep "\b([1-9][0-9]?|1[0-9]{2}|2[0-4][0-9]|25[0-5])\b"
Question4:
Answer4:
egrep "([[:alnum:]]+):.*:\1:" /etc/passwd
七、高级功能
非获取匹配:
正向预查:
-
正则表达式中,可以在子模式内部前面加“?=”来表示:首先,要匹配的文本必须满足子模式前面的表达式;其次,此子模式不参与匹配;
类似于自定义的位于文本末的字符边界\>;
如 Windows (?=[[:digit:]]+\b)匹配结果是 Windows 95 和 Windows 98 中的Windows字段,后面的数字只是作为匹配的依据而已;
反向预查:
-
与正向预查匹配方向相反,可以在子模式内部前面加“?<=”来表示:首先,要匹配的文本必须满足子模式后面的表达式;其次,此子模式不参与匹配;
类似于自定义的位于文本首的字符边界\<;
如 (?<=CNY: )[[:digit:]]+\.[[:digit:]]+ 可以匹配CNY: 128.04和CNY: 23.78 中数字字段,前面的CNY:字段只是作为匹配的依据而已;
八、补充
fgrep:(fast grep)不解析正则表达式,只能对固定的字符串进行搜索,故速度较grep和egrep快
九、参考资料
《Regular Expression Cookbook》
原文链接:https://www.f2er.com/regex/362082.html