Linux学习之正则表达式&grep&egrep

我们经常需要在文档中搜索符合自己要求的内容,这些部分可能分散在文档的各个位置,各个角落。可以利用关键字例如/keyword或者?keyword一个一个的搜索,还有我可能不止想搜索关键字,而是指定一个范围,怎样操作?而且怎样把这些搜索到的内容集中地显示出来?使用正则表达式搜索字串的grep命令和egrep命令就可以满足我们的这个要求。

正则表达式(Regular Expression)是一种字符书写的模式,以行为单位进行字符的处理,透过一些特殊字符的辅助,利用这种模式可以轻易地达到对字符的搜索、删除、取代。上面提到的特殊字符叫元字符。

正则表达式是一种表示法,只要字串处理的相关命令支持这种表示法,就可以调用正则表达式的元字符来进行字符串的处理。

正则表达式分为基本正则表达式和扩展正则表达式。

一、基本正则表达式用到的元字符有这几个方面的分类:

  1. 字符匹配类

元字符代表意义
.任意单个字符
[]指定范围内的任意单个字符
[^]非指定范围内的任意单个字符

2.字符类

元字符代表意义 
[[:digit:]]数字,0-9
[[:lower:]]小字字母,a-z
[[:upper:]]大写字母,A-Z
[[:alpha:]]任何大小字字母,a-z,A-Z
[[:alnum:]]大小写字母及数字,a-z,A-Z,0-9
[[:space:]]所有类型的空白字符,如空格键,TAB键,回车键等产生的空白
[[:punct:]]标点符号
[[:blank:]]空格键和TAB键产生的空白


3.次数匹配类:指定元字符前面的字符出现的次数

元字符代表意义
*
任意次,包括0次
\?0次或1次
\{m\}精确出现m次
\{m,n\}至少m次,最多n次
\{m,\}至少m次
\{0,n\}最多n次
.*任意长度的任意字符

4.位置锚定:指定字串在行中出现的位置

元字符代表意义
^行首锚定
$行尾锚定
^$空白行
\<单词词首
\>单词词尾
\b用于词首同\<,用于词尾同\>

5.分组:将一组字串当作一个字符来引用

分组中的模式匹配到的内容,可由正则表达式引擎记忆在内存中,之后可被引用。用小括号括起来的内容即被正则表达式理解为分组,\(\).如\(abc\).这些()是有编号的,有多层小括号的情况下,如何判断哪一对是一组?以及引用的的哪一组?如\(abc\(def\)g\).*\(lmn\),共有三组(),即有三个分组,"def"为一分组,“abc(def)g”为一分组(包含小分组"def"),还有一个与"abc(def)g"独立的分组"lmn",技术分享,从左到右,红色箭头指向的是第一组,紫色指向的是第二组,分别和后面的同色的右半部括号相对应

"\(abc\(def\)g\).*\(lmn\)\1"后面的"\1"就代表要引用从左边数第1个左括号与跟它相呼应的右括号所包括的内容,即"abc\(def\)g"。"\2"就是引用"def"。所以"\#"就是引用从左边数第几个括号内的内容。

示例:如"\(ab\{1,3\}c\).*\1",有"abbcddeabbc";"abbbcefbb";"abbbbcxxzabbbbc";"abbcssab";这几个字串哪些符合我们的RE格式要求呢?有一条判断准则就是后面"\#"引用的部分和前面的必须完全一致,这样就好判断了。


二、扩展正则表达式用到的元字符

1、字符匹配类  与基本RE相同

2、字符类      与基本RE相同

3、次数匹配类  表示次数的"*"、"?"、"{m,n}等"不用转义字符"\"来转义了,而且增加了"+"来表示重                复前面字符至少一次,与{1,}意义相同。

4、位置锚定    同基本RE

5、分组        "()"括号不用再加上转义字符"\"来转义了

6、或          "|" "a|b"表示"a"或者"b",多个字符的话如"abc|def"表示"abc"或者"def",而不是"abcef"或者"abdef"。所以"|"与"()"配合可以选定字串范围。


三、grep、egrep

grep(globally search a regular expression and print)用法:

grep [options] PATTERN [FILE...]

常用选项:

         -v: 把不包括正则表达式匹配到的字串的行显示出来

         -o: 仅显示匹配到的字串,而非字串所在的行

 -i: ignore-case,忽略字符大小写

 -E: 支持使用扩展正则表达式

 -A #  

 -B #  

 -C #  

egrep(enhanced grep),相当于grep -E


常用选项:

四、示例

题目:写一个模式,能匹配合理的ipv4地址。

解决过程:我把环境设定成从命令"ifconfig"中提取合理的IPV4地址。用支援扩展RE的命令egrep处理。

这个问题对我现在知识水平来说还是有点难度,中间写了很多,有各种不同的匹配结果。有的结果是只能显示出单个的数字,有的是把上千的数字也筛选出来了,最后成功达到目标的写法是:


技术分享

用选项“-o“可以只显示符合要求的字串本身,结果为

技术分享


看下ifconfig的输出:

技术分享

当然还有其它更简洁的RE写法,作为一个数学从小不好的人写出了这么长一串数字,瞬间感觉自己高大上了技术分享技术分享

本文出自 “studyLinux” 博客,请务必保留此出处http://studylinux.blog.51cto.com/2450175/1595597

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。