ホームページ >バックエンド開発 >PHPチュートリアル >正規表現 - 非 PHP チュートリアル
正規表現を使用していますが、様々な機能や構造を使いこなすのはあくまで手段であり、実際の問題を解決することが本当の目的です。実際の問題を解決するには、問題を解決するためのアイデアが必要です。最終的には、正規表現の機能を 3 種類のロジックにまとめることができます。表現の便宜上、それぞれを AND、OR、NOT と呼びます。 。
最近、CIを使って個人給与管理システムを構築する際、ユーザーがログインして特定の機能を使用しているかどうかを確認する必要があり、正規表現-nonを使用しました。要件は次のとおりです:
パス /user、/user/login、/user/register をインターセプトする必要はありません。実際、/profile、/company、/work などのパスをインターセプトして、user_id がセッションに存在するかどうかを確認する必要があります。そうでない場合は、/user/login にジャンプします
最初の観察:
/user と一致するだけです。暫定的なコードは次のとおりです:
01
02
クラス Acl {
03
04
プライベート $CI;
05
06
パブリック関数 __construct() {
07
$this->CI = &get_instance();
08
}
09
10
パブリック関数 auth() {
11
If (!preg_match('/^user.*$/', uri_string())) {
12
$user_id = $this->CI->session->userdata('user_id');
13
if(empty($user_id)) {
14
リダイレクト('/ユーザー');
15
戻る;
16
}
17
}
18
}
19
}
テスト中に、user/change_password を検出できなかったことがわかりました。この機能では、最初に顧客がログインする必要があります。つまり、user/change_password は user.* で除外される必要があります。つまり、正規表現の「non」は除外される必要があります。前述のように使用されます。
「Not」は、正規表現で扱うのが最も難しい論理関係です。直接対応する構造がないため、「not」の処理はより困難になります。
最も単純な「非」は、特定の文字がここに表示されないことを意味します。これは通常、専用の文字グループ [^...] を使用することで解決できるようです。たとえば、二重引用符の文字列を照合する場合、最初と最後の二重引用符は一致しやすいため、内容は絶対に二重引用符ではない (エスケープは当面考慮されない) ため、[^"] で表すことができます。その長さは不確かなので、* で修飾され、式全体は "[^"]*" となり、非常に単純になります。
しかし、物事は本当にそんなに単純なのでしょうか? cat と Cut の例を見てみましょう。c で始まり t で終わる単語を一致させたいが、cut を一致させたくない場合は、c[^u]t と書くことができます。
この式は、最初の文字が c で、その後に u 以外の文字が続き、その後に t が続くことを意味します。はい、カットにマッチするのではなく、猫にマッチすることもあります。ただし、[^u] は「u ではない文字と一致する」という意味であるため、チャート、行為、法廷などと一致することはできません。
次に、[^u] を [^u]+ に変更します。これで問題は解決します。しかし、本当にそうなのでしょうか? [^u]+ は 1 つまたは複数 (無限大まで) の文字を意味しますが、各文字を u にすることはできません。したがって、c[^u]+t は cat と chart を一致させることはできますが、conduct と court を一致させることはできません。
実際、cut と私の間のパス一致の問題は、逐次ネガティブルック関数を使用することで解決できます。
(?!cut) はこのような判定を行うために使用され、cut によって後続の文字列が一致するかどうかを判定し、「現在位置」を移動しません。したがって、これを式の先頭に置き、(?!cut)c[a-z]+t を取得します。この式のロジックは次のとおりです。現在位置の右側の文字列がカットで一致しない場合にのみ、ここから開始して右側に c[a-z]+t を試みます。
さらに一歩進んで、cat と Cut を除外する必要がある場合は、負の順序の look around を (?!c[au]t) に変更できます。これにより、一致するものが確実に猫またはカットではないことが保証されます。 www.2cto.com
最初の質問に戻ります。コードに移動するだけです。コードは次のとおりです:
01
02
クラス Acl {
03
04
プライベート $CI;
05
06
パブリック関数 __construct() {
07
$this->CI = & get_instance();
08
}
09
10
パブリック関数 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
リダイレクト('/ユーザー');
15
戻る;
16
}
17
}
18
}
19
}
作者: kxt