加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

[8-27]正则表达式、扩展表达式以及相关实战

发布时间:2020-12-14 01:00:29 所属栏目:百科 来源:网络整理
导读:本文旨在复习正则表达式,扩展正则表达式,对基本概念、基本用法等作记录 知识储备 正则表达式: 是文本搜索工具,根据用户指定的“PATTERN 模式 ”去 逐行 匹配目标文本,打印匹配到的 行 模式: 由正则表达式的元字符及文本字符,所编写的 过滤条件 元字符

本文旨在复习正则表达式,扩展正则表达式,对基本概念、基本用法等作记录


知识储备


  • 正则表达式:是文本搜索工具,根据用户指定的“PATTERN模式”去逐行匹配目标文本,打印匹配到的

    • 模式:由正则表达式的元字符及文本字符,所编写的过滤条件

    • 元字符:字符不标识其字面意义,用于表示通配或控制功能;

    • 逐行:请注意:正则处理单位是“行”,匹配时去匹配行,输出时输出行

  • BRE与ERE:

    • BRE基本正则表达式,ERE扩展正则表达式

    • 本质区别是[元字符的定义不一样罢了],常用参数是一致的

    • BRE与ERE可互相切换,grep命令中-E使用扩展正则,egrep中-G使用基本正则

  • FRE快速正则表达式

    • 严格来说已经不是正则表达式了,单纯的字符文本匹配罢了

基本正则表达式BRE


Usage:

grep [OPTIONS] PATTERN [FILE...]

常用参数

-v:显示模式匹配不到的行,取反,这里是小写。大写是Version
-i:忽略字符大小写
-o:仅显示能够被模式匹配到的串本身,而不是行
-q:静默模式,无返回值,通过$?可以查看是否匹配到,0是匹配到,1是失败
-E:使用扩展的正则表达式

元字符:

字符匹配

.    匹配任意单个字符,请注意是单个
[] 匹配[]范围内的任意单个字符
[^] 匹配[]范围外地任意单个字符
请注意:[]表示字符集有2种常见的写法
枚举法:[A-Za-z]表示任意1个大小写字母,枚举法即将所有可能出现的字符写在[]里面,可以用","隔开,连续字符用“-”
特殊法:[:upper:]、[:alnum:]、[:alpha:],80);font-family:inherit;font-size:12.960000038147px;font-style:inherit;font-weight:inherit;background-color:inherit;">特殊法本质上是预先定义好的字符集合,按照规定引用即可
在ASNII编码中,[:alnum:]表示大小写和数字,而w 还能够表示大小写字母、数字以及下划线 等价于[_A-Za-z0-9]

次数匹配

*    匹配前一个字符出现任意次,0次、1次、N次都可以
? 匹配前一个字符出现0次或1次
+ 匹配前一个字符出现1次或N次
{m} 精确匹配前一个字符出现了m次,一定是m次
{m,n} 匹配前一个字符至少m次,至多n次,相当于[m,n],有以下2种引申用法
{m,} 至少m次
{0,n} 至多n次
请注意:
1.次数匹配一定是针对前一个字符而言的,就是描述前一个字符出现了多少次
2.有一个特殊用法 .* 表示任意长度的任意字符

位置锚定

行为单位
^ 行首锚定,简而言之就是 紧跟的字符为 行为首的行
$ 行尾锚定,80);font-family:inherit;font-size:12.960000038147px;font-style:inherit;font-weight:inherit;background-color:inherit;">前一个字符为 行尾的行
^$ 特殊用法,表示空行
请注 空行是该行啥都没有,只有一个$行尾结束符。而不是空格,看下面这个实验

wKioL1XjtBiyo4fQAACGKN60BGE105.jpg

词为单位 --> Linux中单词的定义和英文单词不一样,标点符号作为单独单词,连续字母or数字组成算单词
&; 词首锚定
&; 词尾锚定
b 锚定边缘,这玩意儿,既可以锚定词首,也可以锚定词尾,
请注意:
1.通常b可以匹配边缘[词首、词尾],单并非总是等价的,因为正则默认工作在贪婪模式,有时候b匹配的范围大于使用&;&;
2.建议写成&; &; 这样易读,且易于排错

从上面的元字符我们可以看出来一件事,总是在强调匹配单个字符,如果对于lancelancexy如何去描述,或者说如何去匹配连续出现的2次lance呢?

wKioL1Xjtw_xDz3rAACgtRAchEY072.jpg

分组:

使用(ABCDE)将多个字符捆绑起来作为整体,对整体你可以附加字符匹配、次数匹配等等;
分组匹配的内容保存在内置的变量中,这些变量分别是1,2,3 ...
1:从左侧起,第一个左括号以及与之配对的右括号 中间的模式 所匹配到的内容
2:从左侧起,第2个。。。。。你懂的
这就是后向引用:使用变量引用前面的分组括号中的模式所匹配到的
请注意:为什么使用() 而不是()本身?
答:其实这是由于bash决定的,在bash中()有指定意义.而grep命令又是由bash解析然后提请给内核的,所以如果使用()那么bash就不能理解为分组的含义,这就需要使用来告诉bash这个括号表示为分组的含义,这也很好地解释了上面的{} 呵呵

wKiom1Xjt7uyccS2AACtzxpzTHM443.jpg


扩展正则表达式BRE


Usage:

egrep [OPTIONS] PATTERN [FILE...]

常用参数同基本正则表达式,参考前文

元字符:

字符匹配  ---> 同BRE
.
[]
[^]
次数匹配 ---> 同BRE,80);font-family:inherit;font-size:12.960000038147px;font-style:inherit;font-weight:inherit;background-color:inherit;">但是不需要来特殊申明了
*
? 匹配前一个字符0次或1次
+ 匹配前一个字符1次或N次
{m} 精确匹配前一个字符m次
{m,n} 次数在范围[m,n]中
位置锚定 ---> 同BRE
^
$
&;
&;
b
分组 ---> 分组不需要了
()后向引用1 2 3
请注意:特殊A|B 用法
匹配整个|左侧 或 右侧,
C|cat 表示的含义是C或者cat
如果想表示Cat或者cat 请使用 (C|c)at


作业实战


3、显示/etc/passwd文件中以bash结尾的行

答:这道题没啥好说的,最基本的 bash+行尾锚定

wKiom1Xjv6rSAwqsAACRAhw8MpY162.jpg


4、显示/etc/passwd文件中的两位数或三位数

答:这道题除了如下写法,还可以使用&;限定词锚定

wKiom1XjwFHzaZMAAALWDdQyMDk032.jpg

5、显示`netstat -tan`命令结果中以‘LISTEN’后跟0个、1个或者多个空白字符结尾的行

这道题没啥好说的,最后的*也可以用{0,}这种写法,不过要注意[:space:]外侧需要加括号,字符集均如此

wKioL1XjwqvhOy6cAAC39xfHPvQ714.jpg


6、添加用户bash、testbash、basher以及nologin用户(nologin用户的shell为/sbin/nologin);而后找

这道题很有趣,当初我想用cut先切割/etc/passwd把用户名提取出来,然后通过管道送给grep来处理;

但是遇到2个难点:首先管道送给grep是送给grep当参数用,而我需要的是当grep的模式用;其次即便管道成功,那么cut切割后是N列用户名,而我需要是一次送一个用户名,还可能需要使用xargs,限于水平没这么做。

有人说我的&;.*&;范围太广不准确,其实我觉得正是因为范围广才不会出现漏情况。为何呢?因为/etc/passwd这个文件本身就是有规范的,不合法的用户名一定是不存在的,那么我用.*大范围一定能匹配到合法情况 不是吗?

wKiom1XjwNqBQU8rAAGehKGvmvI564.jpg


7、显示当前系统上root、centos或者user1用户的默认shell和UID (请事先创建这些用户,若不存在)

答:使用egrep的 | 匹配用户名 |请注意此时输出的是行!正则是以行为单位匹配和输出的 |cut切割显示

wKioL1Xjx_GTaZeZAADW9fBZIFg586.jpg


8、找出/etc/rc.d/init.d/functions文件中某单词(单词中间可以存在下划线)后面跟着一组小括号的行

这道题解法各有不同,关键是你是如何理解和定义单词这个概念的?紧跟一组小括号,这里需要对()进行转义,否则在egrep中会把()当做分组处理下面是我的写法,我用的是云服务器,截图不是全屏。

wKiom1XjxteyyS02AABaYD94bM8265.jpg

wKioL1XjyUfge4GvAAFBGwOo8sY974.jpg


9、使用echo输出一个路径,而后egrep找出其路径基名;进一步的使用egrep取出其目录名

答:

基名:觉得简单但是当径名结尾有/的时候,输出结果会携带/但这是不需要的,最终使用cut切割来解决豁然开朗

wKioL1XjzRzzkvNfAADbKruKdAo944.jpg

但是这样写其实也是有问题的,因为[:alnum:]匹配有限,如果是下面的情况那么就失效了

wKioL1XjzkeSI4sMAADZWwMWHIY066.jpg

所以很难完完全全地考虑到所有情况解决这个问题,这道题能解决关键在于大部分人命名还是比较正常的。


目录名:这道题没想到太好的办法,多次过滤实现的

wKioL1Xj5tCw5shKAAGsqLUCC0A649.jpg


10、找出ifconfig命令执行结果中1-255之间的数字

思想很重要主要是对1-255分层表述,数字1-9,数字10-99,数字100-199,数字200-249,数字250-255

wKioL1Xjym_jaX2KAAFIVEYjOM8554.jpg

在最初写得时候,我没有在两侧加上(),出现了下面的错误结果,这是因为如果没有()那么会将1028015这类也匹配到,这是为什么呢?因为|是针对整个左侧和右侧而言的,不加()意味着&;[1-9]是一个整体,你懂得

wKiom1XjyHKwiDsOAAG6_MfFchk464.jpg

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读