AIDE技术官网
AIDEZY.COM

正则表达式之大Boss正反预查详解

正则匹配的/u,/i,/s的含义

 

正则表达式之大Boss正反预查详解

说起正则表达式,难点无疑非正则表达式里面的正反预查,

在正则表达式中,有一部分内容并不容易通过文档解释就能搞清楚,那就是预查。预查包括正向预查,反向预查,细分了还各自有肯定预查和否定预查。

说起它是一个难点,但在实际运用中,用得其实并不多,可以这么说,它也是可以用来在正则表达界装逼的,把它理解了无非是给自己增添了新的闪光点,希望站长无陌然写的这篇文章能对你有所帮助。

首先他有4个定义:

零宽度(没有消耗字符)

正预测 (是什么样,负预测–不是什么)

前瞻(往前看)

断言(判断会是什么)

官方的预查解释:

预查的格式:(?=pattern) 
正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 —— Wikipedia 正则表达式字条

下面我就通过几个实例给大家具体讲解一下:

来一个字符串:$str = 'doing playing running wumoram';

现在要你找出ing结尾的词根部分(也就是不包括ing的部分即:do,play,runn)你会怎么找?

首先你第一步肯定会想到先把ing结尾的单词找出来,没有错:

/\b\w+ing\b/

打印结果为:
Array ( [0] => Array ( [0] => doing [1] => playing [2] => running ) )

这时就把ing结尾的所有单词找出来了,那么怎么找出ing前面的几个字母呢?

第二步你肯定会想到用子表达式:

/\b(\w+)ing\b/

打印结果为:
Array ( [0] => Array ( [0] => doing [1] => playing [2] => running ) [1] => Array ( [0] => do [1] => play [2] => runn ) )

好了,这个时候我们就已经把ing前面的字母给打印出来了,但是你会发现我们不仅打印了ing前面的字母,也把他带ing结尾的单词找出来了,我们肯定不是想要这种效果的。那么最后就是要设计到我们的预查了。

最后一步使用预查:

刚刚上面说了预查的格式是什么?

?=是这个吧,好我们就来用,那么怎么用呢?首先我们想到的,他肯定是写在子表达式里面的,这时我们就不是把\w+当做子表达式了,我们把ing当做我们需要的子表达式:(?=ing) 那么这个是什么意思呢?这里我们可以理解为前瞻,也就是向前看,系统检测到ing的存在就停止了,查到ing这里的时候就停止了然后取ing前面的字符,说得通俗易懂点也就是跳过ing取前面的字符,当然官方解释肯定不是我这样解释的,最后你还会发现\b单词结束,怎么跑到子表达式里面去了,它不是应该在外面吗? 这里可以这样理解,前面不是说了吗,系统查到ing就结束,何为结束?也就是没有了,如果把\b放到字表达外部,肯定是不行的,我们的需求是查到ing的时候就直接结束查询取前面的字符,而不是等字表达查完之后再结束,这里有点希望大家能理解

/\b\w+(?=ing\b)/

打印结果为:

Array ( [0] => Array ( [0] => do [1] => play [2] => runn ) )

可以很清楚的发现这时只查出ing前面的字母了。

 

好,我们继续向下衍生:

还是定义一个这样的字符串:
$str = 'doing playing running wumoram';

但是现在我们需要干什么?我们需要找出不是ing结尾的单词。

首先你肯定会想到和找出ing结尾的前面的字母原理是相反的。

何为不是? 也就是不等于,这时我们就要用到 ?!!(感叹号代表不等于)。

同理:

我们需要把/\b\w+(?=ing\b)/进行改造了,怎么改?第一步肯定是把?=换位?!

也就是:/\b\w+(?!ing\b)/ ,首先我们看一下ing它由几个字母组成?一眼就能看出是3位吧,好我们就直接写出表达式:/\b\w+(?!ing)\w{3}\b/,为什么要这样写?这里来怎么给大家解释呢?其实这个真不好用语言来形容,这样理解吧:ing由三个字母组成对吧,我们再来看一下需求是什么?找出不是ing结尾的单词,重点是这个结尾,也即是说找出不是以这个ing结尾的所有单词,在给他变一下,也就是说找出不是以ing结尾的这三个字母的其他所有单词,还有一点需要注意的是:我们需要找出的单词,必须是大于三个字母的,因为ing结尾就已经3个字母了,如果单词只有2位例如un,它也是找不出来的。

/\b\w+(?!ing)\w{3}\b/
打印结果:
Array ( [0] => Array ( [0] => wumoram ) )

可以看到只有wumoran这个字符串就被打印出来了,其他三个ing结尾的都没有打印出来。

 

你以为预测就这样完了?远远没有,其实说实话站长我也不是怎么会的,本身技术也不行的,这个就是仅仅是会一点皮毛而已,我也希望自己能在这条路越走越远。

 

 

下面我再给大家列出和上面两个例子又相反的反预查

这个我就不给大家一个一个的详解了,原理和上面两个是完全相反的一个是正预查一个是反预查,

 

字符串:$str = 'unhappy unluck unset wumoran';

第一个:找出un开头的后面的字母也就是不包括un后面所有的字母(即:happy,luck,set)

正则表达式:

/(?<=\bun)\w+\b/
打印结果:
Array ( [0] => Array ( [0] => happy [1] => luck [2] => set ) )

第二个:找出不是un开头的其他所有单词

 

正则表达式:

/\b\w{2}(?<!un)\w+\b/
打印结果:
Array ( [0] => Array ( [0] => wumoran ) )

 

希望大家再转载的时候能够保留出处,写篇文章挺也不容易,我们的目的也是帮助更多的人。

 

搜一下

海报生成 赞(1) 打赏

来都来了!评论一下呗! 抢沙发

  • QQ (自动获取名称头像等信息|选填)
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址 (选填)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

登录

忘记密码 ?

切换登录

注册