We use regular expressions, and mastering various functions and structures is just a means, and solving actual problems is the real purpose. To solve the real problem, you must have an idea to solve the problem. In the final analysis, the functions of regular expressions can be summarized into three kinds of logic. For the convenience of expression, we call them AND, OR and NOT respectively.
When I was using CI recently to build a personal salary management system, I needed to verify whether the user was logged in and using specific functions, so I used the regular expression - non. The requirements are as follows:
The paths /user, /user/login, /user/register do not need to be intercepted. In fact, paths such as /profile, /company, /work must be intercepted, and then check whether user_id exists in the session. If not, jump Go to /user/login
Initial observations:
Just match /user. The preliminary code is as follows:
01
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
}
During the test, I discovered that I missed detecting user/change_password. This function requires the customer to log in first. Here, user/change_password must be excluded in user.*, which means that the "non" in the regular expression must be used as mentioned earlier.
"Not" is the most difficult logical relationship to handle in regular expressions. Because there is no direct corresponding structure, the processing of "not" is more difficult.
The simplest "non" means that a certain character cannot appear here. This is usually very intuitive. It seems that it can be solved by using the exclusive character group [^...]. For example, when matching double quote strings, the first and last double quotes are easy to match. The content is definitely not double quotes (escaping is not considered for the time being), so it can be represented by [^"], and its length is uncertain. So it is qualified with *, so the whole expression is "[^"]*", which is very simple.
But are things really that simple? Let’s take the example of cat and cut. If you want to match words starting with c and ending with t, but don’t want to match cut, you can write c[^u]t. Is that okay?
This expression means: the first letter is c, followed by a character that is not u, followed by t. Yes, it does not match cut, it can also match cat. However, it cannot match chart, conduct, court, etc., because [^u] means: match a character that is not u.
Then, change [^u] to [^u]+, this should solve the problem. But is it really so? [^u]+ means one or several (up to infinity) characters, but each character cannot be u. Therefore, although c[^u]+t can match cat and chart, it cannot match conduct and court.
In fact, the path matching problem between cut and me can be solved by using the sequential negative look-around function.
(?!cut) is used for this kind of judgment. It judges whether the subsequent string can be matched by cut and will not move the "current position". So we put it at the very beginning of the expression and get (?!cut)c[a-z]+t. The logic of this expression is: only if the string to the right of the current position cannot be matched by cut, start from here and try c[a-z]+t to the right.
If we go one step further and need to exclude cat and cut, we can change the negative order look around to (?!c[au]t). This will ensure that the matched one is definitely not cat or cut. www.2cto.com
Back to the top question. Just go to the code, the code is as follows:
01
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
}
Author: kxt