初识正则表达式

正则表达式是个什么东东?

正则表达式,又称正规表示法、常规表示法(英语Regular Expression,在代码中常简写为regexregexpRE)。在很多文本编辑器里、命令中,通常要使用检索、替换、放行和拒绝那些符合某个模式的文本。而正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。 

摘自《正则表达式之道》)

正则表达式 由一些普通字符和一些元字符metacharacters)组成。普通字符包括大小写的字母和数字,而元字符则具有特殊的含义,我们下面会给予解释。

在最简单的情况下,一个正则表达式看上去就是一个普通的查找串。例如,正则表达式"testing"中没有包含任何元字符,它可以匹配"testing""testing123"等字符串,但是不能匹配"Testing"

要想真正的用好正则表达式,正确的理解元字符是最重要的事情。下表列出了所有的元字符和对它们的一个简短的描述。元字符是工具,组合起来就是方式,普通字符是目标。目标有一个方式有多种。

正则表达式分类标准正则表达式和扩展正则表达式;主要的区别是在于一些元字符的书写方式和支持上,没有根本的区别。

 blob.png

灵活运用这些元字符来对字符进行匹配示例

匹配合理的的IPV4地址

1.0.0.1-239.255.255.255

1IPV4地址是以四组点分十进制来表示的,固定的字符 . 这个 . (点)是固定的有三个把这串字符分为了四组;. (点)在正则表达式内是元字符,那么对它进行匹配需要进行转义;也就是”\.”在正则表达式内才表示为点。

如图所示这样就能匹配出 “.”来了

1.jpg

2、四组的取值范围分别是 “1-239”.”0-255”.”0-255”.”1-255”

   我们先看第一组 “1-239”. 就是在1……….…239中的字符出现一次其实就是123…..239;正则表达式写成1|2|3…..|239肯定可以就是太累了,估计这么写会被直接咔嚓的。哎!1|2|3|4|5|6|7|8|9|10..|99|100…|199|200..|239按照个位十位百位来

1|2|3|4|5|6|7|8|9  不就是[1-9]

|10..|99            不就是[1-9][0-9]

100…|199|          不就是[1][0-9][0-9]

200..|239           不就是[2][0-3][0-9]

组合起来[1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-3][0-9]

验证一下:首先我们看下 ifconfig 显示的内容中都有哪些数字

2.jpg

用我们写好的去匹配下看看是不是1-239

3.jpg

对比下确实0和比239大的数字都没有出现,也就是说这个表达式正常的匹配到我们需要匹配的字符集。

剩下的我们依葫芦画瓢

[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]  0-255

[1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]  1-255

好吧我们把它组合起来

[1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-3][0-9][\.][0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5] [\.][0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5][\.][1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]

对不对先放一边真长啊,一准看花眼。先试试对不对。

4.jpg

哇不对,怎么显示的都是一个一个的单个数啊,对了这是被.(点)给分开的四组字符串,应该分组。  分组再试!

5.jpg

噢耶大功告成。

不过我总觉得有点长,看着太累。

([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-3][0-9])[\.]([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])[\.]([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])[\.]([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])

试着去对表达式进行优化,

1、首先是已经对这个表达式进行了分组是否可以使用引用。

([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-3][0-9])[\.]([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])[\.]\2 [\.]([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])

6.jpg

出错一开始我以为是我的\n的用法不对于是就把命令剪短后再次匹配

7.jpg

发现是可以陪陪的,但是发现没有前后的字符是一样的?回过头来看一遍

\ 引用第n个括号所匹配到的内容,而非模式本身

2、仔细查看表达式发现,里面有[1-9]|[1-9][0-9] 这是01-99 前面这个0-9可以不出现就是0-9   太可恶了这么简单明了的解释都能出错,哎我这智商完蛋了。

? 匹配前面的子表达式零次或一次。(基本表达式需要转意 \)

 [1-9]?[0-9]  应该就是表示对的1-99    

[0-9]?[0-9] 应该表示的就是0-99 

[0-9]出现0次或者1次后面跟上[0-9]出现一次,不就是[0-9]{12} 应也是表示的是0-99

去试试

ifconfig | grep -Eo "([1-9]?[0-9]|1[0-9][0-9]|2[0-3][0-9])[\.]([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])[\.]([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])[\.]( [1-9]?[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"

ifconfig | grep -Eo "([1-9]?[0-9]|1[0-9]{1,2}|2[0-3][0-9])[\.]([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])[\.]([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])[\.]([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])"

8.jpg

所用的命令及参数

grep [option]... 'PATTERN' FILE...
    --color=auto  自动加点颜色显示
    -o: 仅显示匹配的字串,而非字串所在的行
    -E: 支持使用扩展正则表达式
    -F: 不使用正则表达式
sort:  对文件内容进行排序
    sort [option] FILE...
    -f: 忽略字符大小写
    -t: 指定分隔符
    -k: 指定分隔之后要进行排序比较的字段
    -n: 以数值大小进行排序
    -u: 排序后去重

写的不好还请指导O(∩_∩)O~

 

后面的啰嗦一点通配符

通配符:也是一种查找的工具能够进行模糊查找,同时我所了解的就是还有一个网络通配符。

       *: 任意长度的任意字符             

       ?: 匹配任意单字符

       [ ]: 匹配指定范围内的任意单字符 [abc], [a-z], [0-9], [0-9a-z]

       [^]:匹配指定范围以外的任意单字符  [^0-9a-z]

       字符集合:使用需要加[ ]

            [:space:] : 所有空白字符

            [:punct:] : 所有标点符号

            [:lower:] :所有小写字母 [a-z]  不能写成[z-a]

            [:upper:] :所有大写字母 [A-Z]

            [:digit:]  :所有数字     [0-9]

            [:alnum:] :所有数字和字母 [A-Z0-9a-z]

            [:alpha:]  :所有字母       [a-zA-Z]


举个例子:  ls [*]*a.txt   查找以*开头中间有任意字符以a.txt结尾的文件

[root@zhuzw-centos6 tmp]# ls

a  *a**a.txt  aa.txt  a.txt  ceshi.txt  cpvar.sh  keyring-bBocvt  logs  orbit-gdm  pulse-jFNHHBiALmGU  pulse-kCc9R2jshzlv  zhuzw

[root@zhuzw-centos6 tmp]# ls [*]*a.txt

*a**a.txt

[root@zhuzw-centos6 tmp]# ls [^*]*a.txt

aa.txt

[root@zhuzw-centos6 tmp]# ls *[[:space:]]*  匹配空白字符

a    a.txt

[root@zhuzw-centos6 tmp]# ls [a-zA-Z0-9]

ls: 无法访问[a-zA-Z0-9]: 没有那个文件或目录

[root@zhuzw-centos6 tmp]# ls [a-zA-Z0-9].TXT

ls: 无法访问[a-zA-Z0-9].TXT: 没有那个文件或目录

[root@zhuzw-centos6 tmp]# ls [a-zA-Z0-9].txt

a.txt

[root@zhuzw-centos6 tmp]# touch 0

[root@zhuzw-centos6 tmp]# ls [9-0]

ls: 无法访问[9-0]: 没有那个文件或目录

[root@zhuzw-centos6 tmp]# ls [0-9]

0

通配符的这一个表达式表示一整串字符串,从左开始向右结束。主要用于模糊查找。当然了这并不全是通配符的全部功能之前在网络中曾经用过一个网络通配符就是0表示精准匹配,1表示不匹配。

通配符的还有适用于访问控制列表Access Control ListACL

  R1#network 192.168.1.0 0.0.0.255

后面跟的这个和网络掩码是是反的,他表示就是192.168.1.x必须精准匹配,x可以为任意数,意思为宣告192.168.1.0/24 加入ospf区域

192.168.1.0  0.0.0.254匹配出192.168.1.0/24网段中的所有偶数地址

192.168.1.1  0.0.0.254匹配出192.168.1.0/24网段中的所有奇数地址

 

原创文章,作者:东郭先生,如若转载,请注明出处:http://www.178linux.com/1810

评论列表(6条)

  • stanley
    stanley 2015-03-27 23:16

    内容详实,有总结,有实践, 但文章格式太乱,逻辑层次感稍弱,读者初看有些无从下手, 后面的文章可以从这几个方面着手优化。

  • 麦鲸
    麦鲸 2015-04-07 22:33

    写得很好,但是疏忽了一个地方: ifconfig | grep -Eo “([1-9]?[0-9]|1[0-9]{1,2}|2[0-3][0-9])[\.]([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])[\.]([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])[\.]([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])” 应该是“\”首位要锚定,不然会匹配到255.0.0.0 中的55.0.0.0

  • 麦鲸
    麦鲸 2015-04-07 22:35

    不好意思,应该是这样 ifconfig | grep -Eo“\”

  • 麦鲸
    麦鲸 2015-04-07 22:38

    \《 和 \》,英文字符提交出错;首尾要锚定 。

  • 东郭先生
    东郭先生 2015-04-08 08:56

    应该是这样 ifconfig | grep -Eo “\b([1-9]?[0-9]|1[0-9]{1,2}|2[0-3][0-9])[\.]([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])[\.]([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])[\.]([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])\b” 感谢麦鲸同学啊 😀

  • 东郭先生
    东郭先生 2015-04-08 08:58

    \b 和 \ 的效果是一样的。