您的位置:首页 > 其它

偶然碰到的一段正则表达式解析

2016-04-25 14:05 288 查看
今天上午在看CI代码的时候,突然看到了这么一段代码:

CI/system/core/Confing.php

public function system_url()
{
$x = explode('/', preg_replace('|/*(.+?)/*$|', '\\1', BASEPATH));
return $this->slash_item('base_url').end($x).'/';
}


看到这一行代码的时候,有点懵,研究了一上午才弄明白这段代码到底是干什么的。

explode比较简单,在PHP里面是切割字符串的函数,可自行查询PHP手册。

preg_replace是进行正则匹配并替换的函数,最重要的是里面的正则表达式,下面就主要对正则表达式进行解释。

期初看到|*****|的时候我比较不理解,在我的印象中正则表达式都是 /****/这种格式的,也就是我经常看到的定界符是//,所以第一次看到 || 的时候有点不知所措,后来百度才发现原来正则表达式的定界符不仅仅限定于/(关于定界符的详细知识,请自行百度)。为了让大家看的习惯一点,如果上面正则表达式改成 / 作为定界符的样式为

/\/*(.+?)\/*$/

这里要解释一下,改成 / 作为定界符以后,/ 会引起歧义,所以需要反转意符\进行反转意。在这个例子中我觉得CI中原写法看起来比较清楚,所以主要按照开始的格式进行叙述。

/article/6582922.html

在这个正则表达式中 / 是一个需要匹配的字符,*代表0或者多次.$代表结尾,.+?是非贪婪匹配(至于贪婪匹配的概念,请参考/article/6582922.html,我也是看这个才开始理解什么是贪婪匹配的)(不过我个人在这里比较迷惑,因为贪婪匹配并没有发挥作用)

在这里.代表任意字符,+?合起来是惰性匹配任意字符,注意这里的()的用处下面再说,先介绍这个正则表达式的意思。

这个正则表达式我们用PHP中的preg_match_all来就行解释:

echo "<pre>";//这里只是为了让print_r格式显示缩进
$url = "http://CI/show/demo.php/";//示例地址
$url2 = preg_match_all('|/*.+?/*$|', $url, $matches);//注意这里没有加()
print_r($matches);


这个正则表达式显示的结果是

然后我们按照加上括号的正则表达式

preg_match_all('|/*(.+?)/*$|', $url, $matches)

来进行测试,结果是

看出什么区别了吗?

其实这个正则表达式就是将匹配所有的字符,但是(.+?)匹配的是出去开头和结尾的/意外的所有字符,也就是这个正则表达式的目的就是讲开头和结尾的/分割出来。

好了下面,开始说preg_replace中的 \\1是什么意思。

仔细对比一下加不加括号的两种测试结果你就会发现,加了括号以后多了

这就是()里面匹配的项,也就是所需要的项,\\1就是获取匹配结果里面下标为1的那一项,

当$url = "http://CI/show/demo.php/"时

preg_replace('|/*(.+?)/*$|', '\\1', BASEPATH)

就是将这个$url(BASEPATH)进行匹配, 第一个/*匹配结果为空,(.+?)匹配结果为http://CI/show/demo.php,第二个/*匹配结果为/,

所以最后的匹配结果为 http://CI/show/demo.php/,而括号里面的匹配结果为http://CI/show/demo.php,
在这里\\1和$1作用一致(即可以$1可以替换\\1),都是获取下表为1的项的内容也就是

这里面下标为1的项的内容,即去掉开头和结果/的地址.

所以整个preg_replace的作用过程是用(。+?)匹配的内容替代整个BASEPATH,实际目的是去掉开头和结尾的/。

以上为我的个人看法,至于整个函数的作用,需要阅读很多文件才能说清楚而且并不困难,所以不再叙述。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: