当前位置:首页 > 技术文章 > 正文内容

Centos7学习笔记(十六)- 正则表达式高级部分

ivker_lee5年前 (2020-09-16)技术文章296

1、正则表达式工作流程

  1. 取得正则字符串并检查正则语法。

  2. 编译:将正则字符串编译成真正的正则表达式。

  3. 启动正则引擎开始匹配

正则引擎:逐个字符扫描字符串并与编译后的正则表达式的各个元素进行匹配。

何为正则元素呢?

  • 纯字符组合,比如“abc123”,那么每一个字符都是一个正则元素

  • [a-z]这样的样式,那么视中括号[]为一个整体作为正则元素,中括号内的内容是限定的匹配范围

  • 字符匹配的反斜线序列也是一种正则元素

  • 字符.是一个独立的正则元素,它除了不能匹配\n,其他任意字符都能匹配

  • 所有的*、?、{m}、{m,}、{m,n}、{,n}这几个正则,都是作为量词存在的,即计量数量,这些量词,不能作为独立的正则元素,但是是作为修饰符存在,修饰定义它前面的字符或子表达式内容。

  • |分隔符两端的,比如a|b这样的表达,那么竖线两端的字符或子表达式都是正则元素

  • ()圆括号将视为一个整体正则元素,比如sed中常用的(.*)。

2、正则表达式匹配流程

正则是按每一轮的方式匹配,每轮,都要从正则的第一个元素从头开始匹配。

即,被匹配的字符串或内容被逐个字符扫描去匹配正则元素,若成功,下一字符匹配下一个正则元素,若不成功,则消耗掉已经被扫描匹配的字符,剩余的字符,进入下一轮完整匹配。

3、正则引擎

DFA类——确定有穷状态机,

    将扫描到的字符与所有可能的分支一次性进行匹配

    不断淘汰匹配失败的分支,最终确定一个成功的分支

    DFA对字符串中的每一个字符,只扫描匹配一次,不会回溯,也没有字符交还的过程

NFA类——非确定有穷状态机

    它对正则表达式中的所有分支做标记,以便匹配失败时,可以根据标记回头匹配其他分支,然后从中选择一个分支优先匹配,剩余分支先放着,在所选分支匹配失败时,再回头选择其他分支

    如果某个分支匹配成功,则剩下的分支就直接丢弃

    它会记录所有可能的分支,每个分支的匹配都是不确定的,失败的时候回头重新匹配其他分支

    NFA有可能在匹配失败后,交还字符,然后回溯,并对某个字符进行多次匹配

DFA、NFA混合类

[root@c7study /home/study/.ssh]# echo '404 not found'|perl -nE '/not|not found/;say $&'           #《========$&是表示匹配的内容
not
[root@c7study /home/study/.ssh]# echo '404 not found'|perl -nE '/not found|not/;say $&'
not found
[root@c7study /home/study/.ssh]# echo '404 not found'|egrep 'not|not found'
404 not found

4、什么是回溯?及影响?

回溯就是在有分支或者贪婪匹配时,为了正确获取匹配结果,必须在分支匹配失败或贪婪匹配内容过多后,交还字符,然后回头重新进行字符扫描匹配。

它的显著影响是很有可能大大降低正则匹配的效率,显著的提高了匹配花费时间。

image.png

5、反斜线序列正则

①字符匹配类

\n——匹配换行符

\N——匹配非换行的字符

\w——匹配单词构成部分,等价于[_[:alnum:]]

\W——匹配非单词构成部分,等价于[^_[:alnum:]]

\s——匹配空白字符,等价于[[:space:]]

\S——匹配非空白字符,等价于[^[:space:]]

\d——匹配数字,等价于[0-9]

\D——匹配数字,等价于[^0-9]

\\——匹配\字符

②位置锚定类

\b——匹配单词边界处(开头和结尾),如\bword\b

\<——匹配单词开头位置

\>——匹配单词结尾位置,所以,\<和\>是配对使用的

\B——匹配非单词边界处的位置

\A——匹配字符串的绝对行首

\z——匹配字符串的绝对行尾

\Z——匹配字符串的行尾,如果行尾有换行符,那么匹配换行符前的位置

\G——第一次匹配的位置,全局匹配有效,也称为位置粘滞

^——匹配每一行行首

$——匹配每一行行尾,换行符前的位置

image.png理解这些位置

那么,^$为啥能匹配空行?看下图就能理解:

image.png图中以字符串abc\n\n123\ndef为例,既符合^又符合$位置的,只有空行那一行。

6、贪婪匹配、非贪婪匹配、占有优先匹配

上述正则元素中解释的作为修饰符存在的量词,是引起贪婪匹配的原因。那么什么是非贪婪匹配和占有优先匹配呢?先看其具体表达

贪婪匹配非贪婪匹配占有优先匹配
**?*+
?
???+
++?++
{m}

{m,}{m,}?{m,}+
{m,n}{m,n}?{m,n}+
{,n}{,n}?{,n}+
  • 非贪婪匹配时,{m}?和{m,n}?是等价的,因为最多都匹配m次。

  • ??在非贪婪匹配时,它匹配任意一个字符、位置、空字符,但这种使用方式基本不会用

  • 在perl中,因为不支持{,n}的方式,所以也没有对应的非贪婪匹配{,n}?和占有优先匹配{,n)+

  • 关于{m},因为它本身是精确匹配,所以{m}?和{m}+也并无意义。

非贪婪匹配,是跟贪婪匹配完全相反的匹配。贪婪匹配是尽可能多的匹配,然后慢慢交还字符,而非贪婪匹配,则是尽可能少的匹配,然后若是不能完全匹配,则逐个消耗匹配成功的字符。

image.png

image.png

占有优先匹配,它是在贪婪匹配的基础上,所有匹配成功的字符都被消耗掉,不会再交还进行回溯。所以,等同于零宽断言。一般而言,占有优先匹配的+后不应有字符,特别是*+这个,它会消耗掉其后的所有字符元素。

7、环视锚定

环视锚定也用于匹配位置,也是一种位置锚定。位置锚定,就不会消耗字符元素。

几种写法:

(?=...)——从左向右顺序环视,这里的...表示要匹配的内容,比如a(?=\d)表示锚定a字符右边开始是数字的情况。

(?!...)——从左向右顺序环视的取反,...仍然表示要匹配的内容,但是要取反内容,比如a(?!\d)表示a字符右边不是数字的情况

(?<=...)——从右向左逆序环视,...表示要匹配的内容,比如(?<=\d)a表示字符a左边是数字的情况匹配成功

(?<!...)——从右向左逆序环视,但是匹配内容取反。比如(?<!\d)表示字符a左边是非数字情况匹配成功

8、分组捕获

分组捕获这个概念,其实就是sed命令中常用的(.*),然后反向引用\1这种形式。用()来把内容视为一个整体,然后“捕获”,并可以引用。

分组捕获后匹配的结果,会被保存在变量中,可以使用\n或$N(perl支持)来取得各分组捕获所匹配的结果。

还有一些分组捕获的方式,主要是在perl中支持。下面来分类解释:

①命名捕获

命名捕获的意思是将捕获匹配的内容,独立命名,使捕获内容既可以传统引用,又可以用命名引用。在引用的时候,可以用传统的\n或$n方式引用,也可以用\k<名字>的方式引用。在正则外部,比如perl中,可以用$+{名字}

使用形式是(?<NAME>pattern)。其中,NAME是要定义的名字,pattern是需捕获内容。

在引用的时候,可以用传统的\n或$n方式引用,也可以用\k<NAME>的方式引用。在正则外部,比如perl中,可以用$+{NAME}来引用。

image.png

②匿名捕获(只分组不捕获)

匿名捕获,即是将匹配内容只是做分组匹配,并不讲匹配内容赋予变量以引用。

使用形式:(?:pattern)

③固化分组

固化分组其功能上跟占有优先匹配(*+、?+、++、{m}+、{m,n}+、{m,}+)是等价的。匹配上了,即占有(占有字符了)了,不交还字符,不回溯了。

固化分组,也是没有捕获功能的。

使用形式:(?>pattern )

image.png

9、匹配模式的修饰符

这里的“修饰符”指的都是perl支持的方式,功能上,更像是一个开关,使原本不能匹配的方式,通过加修饰符,变的能匹配。主要用在编程语言环境,比如perl。因为编程语言环境,允许一个字符串,包含各种特殊的字符,比如\n\t这种。

有如下若干修饰符:

i:作用,忽略大小写

image.png

m:作用,让^和$能匹配含有像\n这样特殊字符的字符串的每一行行首和行尾。(注意:这不是grep、awk、sed这3个按行处理文字内容的常规处理方式)

image.png

s:作用,让.能匹配\n这样的换行符。看下图示例:

image.png

x:作用,允许正则表达式使用空白符号(甚至加#注释),免得使正则表达式晦涩难懂,这称之为free-spacing。在使用x修饰时,会使要匹配处理的内容中原本的空白符号失去意义,这时候,就必须要用\s或者[:space:]去匹配空白符号。

$ans="cat sheep tiger";

$ans =~ /(\w) *(\w) *(\w)/;       # 正常情况下的匹配表达式

$ans =~ /(\w)\s*   (\w)\s*   (\w)/x;

$ans = ~ /        (\w)\s*      # 可以加上本行注释:匹配第一个单词        (\w)\s*      # 可以加上本行注释:匹配第二个单词        (\w)         # 可以加上本行注释:匹配第三个单词        /x;

$ans =~ /         (\w)\Q \E   # \Q \E强制将中间的空格当作字面符号被匹配         (\w)\Q \E         (\w)        /x;

o:作用,使正则表达式只被编译一次,编译后的结果被缓存下来,以便循环调用。o修饰符在有循环处理正则的情景中,非常有用,能大大缩减处理时间。如下图中的示例:

image.png

g:作用,全局匹配。

1、默认情况下,正则匹配会在匹配成功一次后,就退出匹配。(grep是全局匹配的,不算在内)

2、加入g修饰符后,正则匹配会在成功匹配一次后,设置一个指针,该指针位于第一次匹配成功的结果之后。其作用是标记位置,以便下一轮全局匹配从当前标记位开始。如果第2轮或者某一轮全局匹配失败,则默认情况下,该指针会被重置到需匹配的内容(字符串或者文本内容等)的开头。

image.png

3、为了解决上述第二条指针重置的问题,引入c修饰符,使指针在匹配失败后,保持不动,后续全局匹配,能继续处理后续内容。

image.png

4、位置粘滞\G的作用。\G针对全局匹配时使用,要求指针后的内容在下一轮匹配时必须成功,否则指针重置。

image.png

image.png

5、g修饰符,基本都是用在循环结构中,以便重复匹配能够成功。

分享给朋友:

相关文章

Centos7学习笔记(二)-基础命令(二)

Centos7学习笔记(二)-基础命令(二)

3、Linux基础命令1、date参数:-s  设置日期-d  display time described by STRING, not 'now'---用日期表示法的完整字符串(比如“1day”,“2month”,“1year”)来显示时间,但不准用“now”。实例如下:[root@ecs-ryCz8 /home/study]# date +%F -d "now" 2020-...

 Centos7学习笔记(十三)- 一个解压用脚本的详细说明

Centos7学习笔记(十三)- 一个解压用脚本的详细说明

#!/bin/bash cd /home/tar #ls出该目录下的文件,并导出所需文件名到file.log文件中 ls *.tar.gz >file.log ls *.tgz >>file.log 2>/dev/null ls *.tar.bz2 >>file.log 2>/dev/null #统计file.log到底有多少文件 num=$(cat&...

 Centos7学习笔记(十二)- inotify+rsync与sersync

Centos7学习笔记(十二)- inotify+rsync与sersync

1、inotify-tools的安装yum安装,安装好epel源后,yum -y install inotify-tools源码安装:wget  https://github.com/inotify-tools/inotify-tools/releases/download/3.20.2.2/inotify-tools-3.20.2.2.tar.gz tar zxvf inotify-tools-3.20.2.2.tar.gz cd inot...

Centos7学习笔记(七)— 性能调优一

Centos7学习笔记(七)— 性能调优一

1、nice,renice  调整进程nice值,让进程使用更多的CPUnice值   #范围,  -20 ~ 19  越小优先级越高 普通用户0-19作用:以什么优先级运行进程 。默认优先级是0语法: nice  -n 优先级数字   命令例:# nice -n -5 vim a.txt   # vim进程以-5级别运行查看:ps -axu | grep a.txt[root@xueg...

Centos7学习笔记(二十三)- nginx的keepalived高可用

Centos7学习笔记(二十三)- nginx的keepalived高可用

一、什么是keepalivedkeepalived最初是为LVS设计的,用于管理并监控LVS集群中各个服务节点的状态,后来又加入了可用实现高可用的VRRP协议支持。VRRP是Virtual Router RedundancyProtocol(虚拟路由器冗余协议)的缩写,VRRP出现的目的就是为了解决静态路由单点故障问题的,它能够保证当个别节点宕机时,整个网络可以不间断地运行。这里的VRRP协议,就是纯粹的网络中使用的VRRP协议。二、keepalived工作原理这里说“keepalived工作原...

 Centos7学习笔记(十一)- nfs服务器搭建

Centos7学习笔记(十一)- nfs服务器搭建

nfs服务本质上是通过rpc调用提供服务的,所以,其依赖rpcbind程序相关组件运行。而且,rpc服务必须先启动,nfs服务才能正常使用。以下是安装配置:1、服务端a)安装软件yum -y install nfs-utils rpcbind                                    &nb...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。