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

来源:互联网 发布:朗读爱好者软件 编辑:程序博客网 时间:2024/06/05 15:02

今天上午在看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中原写法看起来比较清楚,所以主要按照开始的格式进行叙述。

http://www.cnblogs.com/taek/archive/2012/02/07/2341654.html

在这个正则表达式中 / 是一个需要匹配的字符,*代表0或者多次.$代表结尾,.+?是非贪婪匹配(至于贪婪匹配的概念,请参考http://www.cnblogs.com/taek/archive/2012/02/07/2341654.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,实际目的是去掉开头和结尾的/。

以上为我的个人看法,至于整个函数的作用,需要阅读很多文件才能说清楚而且并不困难,所以不再叙述。



0 0
原创粉丝点击