一段正则表达式的分享


一、正则表达式

2022年7月14日,我们小组偶然遇到了一个正则表达式,感觉蛮复杂的,当时把每个人都难住了,后来花了一些时间终于弄清楚了。该正则表达式内容如下:

/^(?:[^#<]*(<[wW]+>)[^>]*$)/

读者有兴趣可以先自行思考一下,然后再继续看后面的内容。

二、分析过程

通常看到一个正则表达式,要想理清楚其中的逻辑,需要先进行一波简化。
首先从左往右看,正则的开头出现了一个^,表示限定开头,末尾的$表示限定结尾。
接着看到在()中出现了?:,这是什么意思呢?需要先了解一下以下内容:
()中的内容本身表示捕获分组,该内容被正则识别后,会被保存起来备用。而
如果变成这样(?:),就表示非捕获分组,和捕获分组唯一的区别在于,非捕获分组匹配的值不会被保存起来,这样对于服务器而言,减少了一个存储的过程,减少了资源的消耗,也可以提高正则的效率。
因此对于分析这个正则表达式本身而言,括号中有没有?:没有任何区别,可以做第一次简化:

/^([^#<]*(<[wW]+>)[^>]*$)/

接着看[^#<],别被#吓到了,其实经过测试,^#<和^<在这里没有任何区别,都是表示不匹配<
因此做第二次简化:

/^([^<]*(<[wW]+>)[^>]*$)/

接着做第三次简化,很显然,*的存在完全可以忽略,直接删掉,从而实现第三次简化:

/^([^<](<[wW]+>)[^>]$)/

现在看末尾的$,它放在括号里面和括号外面没有什么区别,因此直接把它移动到外面,实现第四次简化:

/^([^<](<[wW]+>)[^>])$/

现在再来简化一次,就是+所起的作用是连接,可以直接删除,因此做第五次简化如下:

/^([^<](<[wW]>)[^>])$/

可以看到,中间的括号表达的含义就是,只能接受或者这两种情况。
左边的中括号表示,可以接受一个非<的任意字符,注意是可以,而不是必须。
右侧的中括号也是一样,可以接受一个非>的任意字符,注意是可以,而不是必须。
因此符合规则可以有无数个,最核心的就是必须包含或者,首尾可以各跟一个非尖括号的任意字符。
分析完毕,可以用如下php代码测试一下试试:

<?php 
$a=$_REQUEST['a'];
var_dump(Preg_match_all('/^(?:[^#<]*(<[wW]+>)[^>]*$)/',$a,$b));
echo '<br />';
?>

首先测试传参<w><W>如下:
传参
在这里插入图片描述
首尾任意各传一个非尖括号的字符试试:
在这里插入图片描述
成功了,说明前面的分析正确。


三、小结

本文将工作中遇到的一段正则表达式分享给大家,希望对大家有所帮助。

猜你喜欢

转载自blog.csdn.net/weixin_64551911/article/details/125836337
今日推荐