今天上午在看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,实际目的是去掉开头和结尾的/。
以上为我的个人看法,至于整个函数的作用,需要阅读很多文件才能说清楚而且并不困难,所以不再叙述。