PHP头条
热点:

正则表达式-非


我们使用正则表达式,熟练掌握各种功能和结构只是手段,解决实际的问题才是真正的目的。要解决真正的问题,就必须有解决问题的思路,正则表达式的功能,说到底,可以归纳为三种逻辑,为了表述方便,我们分别称为与、或、非。

最近用CI在做个人工资管理系统的时候,需要验证用户是否登录和使用特定的功能,用到了正则表达式-非。需求如下:

路径/user, /user/login, /user/register不需要进行拦截,其实诸如/profile, /company, /work的路径都要拦截,然后检查session中是否存在user_id,没有的话就跳转到/user/login

初步观察:

只要对/user进行匹配就行了。初步代码如下:

01
<?php
02
class Acl {
03
 
04
    private $CI;
05
 
06
    public function __construct() {
07
        $this->CI = &get_instance();
08
    }
09
 
10
    public function auth() {
11
        if (!preg_match('/^user.*$/', uri_string())) {
12
            $user_id = $this->CI->session->userdata('user_id');
13
            if(empty($user_id)) {
14
                redirect('/user');
15
                return;
16
            }
17
        }
18
    }
19
}
测试的时候才发现漏了检测user/change_password,这个功能是需要客户首先登录的,这里就要在user.*中排除user/change_password的,也就是前面说的要用到正则中的“非”。

“非”是正则表达式中最难处理的逻辑关系。因为没有直接对应的结构,“非”的处理比较吃力。

最简单的“非”,意思是此处不能出现某个字符,这一点通常很直观,似乎用排除型字符组[^…]就可以解决。比如双引号字符串的匹配,首尾两个双引号很容易匹配,其中的内容肯定不是双引号(暂时不考虑转义的情况),所以可以用[^"]表示即可,其长度不确定,所以用*来限定,所以整个表达式就是"[^"]*",非常简单。

但是,事情果真都如此简单吗?我们举cat和cut的例子,如果希望匹配c开头,t结尾的单词,但不希望匹配cut,可以写成c[^u]t,是否就可以了?

这个表达式的意思是:最开头的字母是c,之后是一个不为u的字符,之后是t。没错,它确实不会匹配cut,也可以匹配cat。但是,chart、conduct、court等等,它也没法匹配,因为[^u]的意思是:匹配一个不是u的字符。

那么,把[^u]改成[^u]+好了,这样应该就可以解决问题了。但是真的如此吗?[^u]+的意思是,一个或若干(最多到无穷)个字符,但每一个字符都不能是u。所以,尽管c[^u]+t能匹配cat和chart,却不能匹配conduct和court。

其实cut和我的路径匹配问题可以用顺序否定环视功能来解决。

(?!cut)就是用来进行这种判断的,它判断之后的字符串能不能由cut匹配,也不会移动“当前位置”。所以我们将它放在表达式的最开头,得到(?!cut)c[a-z]+t。这个表达式的逻辑是:只有在当前位置右侧字符串不能由cut匹配的情况下,才从这里开始,向右尝试用c[a-z]+t。

如果我们更进一步,需要排除掉cat和cut,可以把否定顺序环视改为(?!c[au]t)。这样就能保证,匹配到的肯定不是cat或者cut。www.2cto.com

 

回到最上面的问题。直接上代码吧,代码如下:
 
01
<?php
02
class Acl {
03
 
04
    private $CI;
05
 
06
    public function __construct() {
07
        $this->CI = & get_instance();
08
    }
09
 
10
    public function auth() {
11
        if (!preg_match('/^(?!user\/change_password)user.*$/', uri_string())) {
12
            $user_id = $this->CI->session->userdata('user_id');
13
            if(empty($user_id)) {
14
                redirect('/user');
15
                return;
16
            }
17
        }
18
    }
19
}
作者:kxt

www.phpzy.comtrue/phprm/15538.htmlTechArticle正则表达式-非 我们使用正则表达式,熟练掌握各种功能和结构只是手段,解决实际的问题才是真正的目的。要解决真正的问题,就必须有解决问题的思路,正则表达式的功能,说到底...

相关文章

    暂无相关文章
相关频道:

PHP之友评论

今天推荐