shell之正则表达式

        学习过编程语言的应该都听说过正则表达式这个词,那么正则表达式到底是什么呢?接下来就让我们来了解一下。

       1、正则表达式简介

         正则表达式是用于描述一组字符串特征的模式,用来匹配特定的字符串。通过特殊字符+普通字符来进行模式描述,从而达到文本匹配目的。

        我们一般使用正则表达式是来进行模糊匹配。

        正则表达式的实验场景有很多,一般我们在浏览网页的时候

  • 验证:表单提交的时候,对用户名和密码的验证;
  • 查找:从海量的数据和信息里面提取指定内容;例如在一批URL中查找指定的URL;
  • 替换:将指定格式的文本,进行正则匹配查找,找到之后进行特定替换;例如在vim编辑器里进行文本替换的时候;

         2、正则表达式的三要素

        构建正则表达式有三个重要的指标,那就是正则表达式的三要素:字符类,数量限定符,位置限定符。当然有时还会有一些特殊符号。

        正则表达式与语言无关。

     3、grep工具的了解

     相信看到grep工具,我们应该不会很陌生,因为在对文本内容进行查找或者过滤筛选的过程中我们经常会用到。那么grep工具到底有什么用处呢?

     (1)grep工具的简介 

       grep (缩写来自Globally search a Regular Expression and Print)是一种强大的文本搜索工具,它能使用特定模式匹配(包括正则表达式)搜索文本,并默认输出匹配行。

        grep的工作方式是这样的,它在一个或多个文件中搜索字符串模板。如果模板包括空格,则必须被引用,模板后的所有字符串被看作文件名。搜索的结果被送到屏幕,不影响原文件内容。

       grep可用于shell脚本,因为grep通过返回一个状态值来说明搜索的状态,如果模板搜索成功,则返回0,如果搜索不成功,则返回1,如果搜索的文件不存在,则返回2。我们利用这些返回值就可进行一些自动化的文本处理工作。

     grep命令中允许指定的串语句是一个正则表达式,这是一种允许使用某些特殊键盘字符的指定字符串的方法,这种方法中的特殊键盘字符可以用于代表其他字符也可以进一步定义模式匹配工作方式。例如:grep ".*hood" essay1。该命令将在文件essay1中搜索,显示出包含带有字符串hood的字的每一行。命令行中的点表示的是hood之前可以有任意字符,星号指的是在字符串之前点号所表示的任意字符可以有任意个(其中的双引号是可有可无的,但是当语句中包含短语或者空格时就必须加双引号)。

     值得一提的是,grep工具在进行正则匹配的时候使用的是贪心匹配。grep工具在进行查找的时候是按照行来进行查找和过滤的。

   (2)grep命令   

           -E: 使用扩展正则匹配,后面介绍

           --color: 将匹配的到内容进行语法高亮

           -v:反检索,只显示不匹配的行。

           -i :忽略大小写差别。

           -q:安静模式匹配,取消显示,只返回退出状态。0则表示找到了匹配的行。

          -R:递归的读取目录下的所有文件,包括子目录。 比如grep -R 'pattern' test会在 test 及其子目录下的所有文件中,匹配 pattern。

          -V:显示软件版本信息。

          -o:只显示与正则表达式匹配的部分。

          -n:显示匹配的行,并且在匹配的行前面打印行号。

          -b:打印匹配行前面打印该行所在的块号码。
          -c:只打印匹配的行数,不显示匹配的内容。
          -f:从文件中提取模板。空文件中包含0个模板,所以什么都不匹配。
          -h:当搜索多个文件时,不显示匹配文件名前缀。
          -l :打印匹配模板的文件清单。
          -L: 打印不匹配模板的文件清单。
          -s:不显示关于不存在或者无法读取文件的错误信息。

          -w:如果被\<和\>引用,就把表达式做为一个单词搜索。

     下面就使用grep工具来验证一下正则表达式的三要素。

     字符类

字符 含义
. 匹配任意一个字符
[] 匹配括号中的任意一个字符
- 在括号内表示字符范围
^ 位于[]括号的开头,匹配除括号中的字符之外的任意一个字符
[[:xxx:]] grep工具预定义的一些命名字符类([[:alpha:]]匹配一个字母,[[:digit:]]匹配一个数字)

测试用例:

  

  

   数量限定符

字符 含义
紧跟在它前面的单元应匹配零次或一次
+ 紧跟在它前面的单元应出现一次或多次
* 紧跟在它前面的单元应匹配零次或多次
{N} 紧跟在它前面的单元应精准匹配N次
{N,} 紧跟在它前面的单元应匹配至少N次
{,M} 紧跟在它前面的单元应匹配至多M次
{N,M} 紧跟在它前面的单元应匹配至少N次,至多M次
测试用


位置限定符

字符 含义
^ 匹配行首的位置
$ 匹配行末的位置
\< 匹配单词开头的位置
\> 匹配单词结尾的位置
\b 匹配单词开头或结尾的位置
\B 匹配非单词开头或结尾的位置

测试用例:



特殊符号

字符 含义
\ 转义字符,普通字符转义为特殊字符,特殊字符转义为普通字符
() 将正则表达式的一部分括起来组成一个单元,可以对整个单元使用数量限定符
| 连接两个子表达式,表示或的关系
测试用例:


        可以看出,()表示将其所包含的内容作为一个整体,作为一个单元,然后可以使用数量限定符来进行修饰限定。

         在我们使用grep工具进行测试的时候,一直都有一个-E选项,那这个选项到底有什么用呢?去掉会有什么不同呢?


   我们可以发现,在去掉-E选项之后,匹配结果出错,并没有按照我们的期望去正常匹配。这到底为什么呢?我们先来看两个概念:

   基准正则表达式:Basic

   扩展正则表达式:Extended

区别:

      正则表达式的Extened规范和Basic规范基本相同,只是在Basic规范下,有些字符如 ?+ | {} ()应该被解释为普通的字符,要表示上述特殊字符必须要在前面加上\进行转义。在Extended规范下,?+| {}()应该被解释为特殊字符,要取其字面值,也必须对其进行转义。

      所以grep工具带上-E选项,表示使用扩展正则来进行匹配,若没有,则表示使用基准正则来匹配。上述问题就可以如下解决:


      那么,如果在目标字符串中本来就包含了这些字符,想要匹配的话,我们应该怎么做呢?当然,这下就需要用到刚刚说的\转义了。


其他常用通用字符集及其替换

符号 替换正则 匹配
\d [0-9] 数字字符
\D [^0-9] 非数字字符
\w [a-zA-Z0-9_] 数字字母下划线
\W [^\w] 非数字字母下划线
\s [_\r\t\n\f] 表格,换行等空白区域
\S [^\s] 非空白区域

测试用例:


在上述测试用例中,-E选项进行\d匹配的出错,这是为什么呢?因为正则表达式分为三类:

   基准的正则表达式:Basic(BREs)

   扩展的正则表达式:Extended (EREs)

   Perl的正则表达式: (PREs)

grep , egrep 正则表达式特点:

   grep 支持:BREs、EREs、PREs 正则表达式

   grep 指令后不跟任何参数,则表示要使用 ”BREs“

   grep 指令后跟 ”-E" 参数,则表示要使用 “EREs“

   grep 指令后跟 “-P" 参数,则表示要使用 “PREs"

所以,要解决上述问题,必须使用-P 选项

    在了解了什么是正则表达式以及简单实用了正则表达式后,接下来做两个小练习。

  首先创建一个文件file


(1)在一个文件中查找电话号码


(2)在一个文件中查找日期


(3)在匹配IP地址


    3、零宽断言

    断言用来声明一个应该为真的事实。正则表达式中只有当断言为真时才会继续进行匹配。 接下来的四个用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像\b,^,$ 那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。

  零宽断言: 不匹配长度,只是为了用正则表达式来确定一个位置。

(1)(?=exp)也叫零宽度正预测先行断言: 它断言自身出现的位置的后面能匹配表达式exp。

(2)(?<=exp)也叫零宽度正回顾后发断言:它断言自身出现的位置的前面能匹配表达式exp。


  好了,以上就是我所总结的关于shell的正则表达式的相关概念及测试用例。




猜你喜欢

转载自blog.csdn.net/weixin_38175489/article/details/80915616