2012年11月12日 星期一

正規表式法

/ /  宣告正規表式法的範圍 ( ) 多個圓弧號裡面的字串,可以用 $1, $2 ... 當成變數再次呼叫。
[ ] 裡面的內容,只會匹配一個字元。
[ ] 裡面的 ^ 代表排除。
 { } 設定字串出現的次數
? 前一個字符出現 0 或 1 次
* 前一個字符出現 0 次以上 + 前一個字符出現 1 次以上 ======================================================
 檢查網址
<?php
$url = "http://aaa123.bb_bb.ccc-ddd.com/xxx/yyy zzz/index,pa@ge.php?id=456 789&country=tw"; 
$pattern = "/^(http:\/\/)([a-zA-Z0-9._-]+)([\w\/\s@?=&,._-]+)/";
preg_match($pattern, $url, $matches);
?>
結果:
Array
(
    [0] => http://aaa123.bb_bb.ccc-ddd.com/xxx/yyy zzz/index,pa@ge.php?id=456 789&country=tw
    [1] => http://
    [2] => aaa123.bb_bb.ccc-ddd.com
    [3] => /xxx/yyy zzz/index,pa@ge.php?id=456 789&country=tw
)

說明:
1.三段圓弧號,表示字串(網址)要依照這三個圓弧號的順序,逐一比對。
2. "/^(http:\/\/)([a-zA-Z0-9._-]+)([\w\/\s?=&,._-]+)/"   => http:// 開頭
3. "/^(http:\/\/)([a-zA-Z0-9._-]+)([\w\/\s?=&,._-]+)/"   => 主機名稱(FQDN):可以是 a 到 z ,或是 A 到 Z , 或是0 到 9 ,或是 . _ - 這三個符號。   => + 等於前面的符號出現一次以上。
4. "/^(http:\/\/)([a-zA-Z0-9._-])([\w\/\s@?=&,._-]+)/"   => \w 等於 a-zA-Z0-9   => \/ 等於斜線 /   => \s 等於空白 ( 瀏覽器會把空白轉換成 %20 )   => 再後面的每個符號都代表字面上的意義,這些符號都可能是網址的一部份。(可以當檔名的符號都可以是網址的一部份。 但這些不行: / \ : * ? < > |  
======================================================
 檢查檔案路徑
<?php
$url = "/var/www/vhosts/example.com/contactus/index.php";
$pattern = "/(.)*[\/]/"; //取得  不含檔名的路徑
    if(preg_match($pattern, $url, $matches))
        echo 'yes';
    else
        echo 'no'; echo "<pre>"; print_r($matches); echo "</pre>";
?>
結果: yes
Array (
     [0] => /var/www/vhosts/example.com/contactus/
     [1] => s )
備註:本例練習用。其實可以用 PHP 內建的函數:dirname($str)
======================================================
找出檔案名稱
本例可以配合上面的一起看,不過用的函數不一樣。
過程:把路徑找出來後,用空字串替換掉,只剩下檔案名稱。
$str = "/var/www/vhosts/example.com/contactus/index.php";
$pattern = "/(.)*[\/]/";
echo preg_replace($pattern, '', $str)
結果: index.php 備註: 可以用 PHP 內建的函數:basename($str)
======================================================
<?php
/*
◎下面字串裡面的123 456 789,可以用 \w \d 或其它表示法代替。
◎下面的例子有些即使有問題,但仍具參考價值,目的只是在瞭解語法。會用這些例子只是一時找不到適當的例子,也許哪天在某個場合,或是稍加變化之後,可以派的上用場。
◎下面的例子有些即使不使用 (? 這種方式也可以達成。只是對用法做基本說明。
*/

// (?=
echo preg_match('/123(?=456)/', '123456789', $matches);
//1 => 456的前面必須是123
echo preg_match('/123(?=456)(789)/', '123456789', $matches);
//0 => 456的前面必須是123,但是456本身不捕獲。也就是說,真正要抓的是123789,但是又規定123後面要接456。(這其實是個有問題的句子。)

// (?!
echo preg_match('/123(?!456)789/', '123456789', $matches);
//0 => 456的前面不能是123

// (?<=
echo preg_match('/(123(?<=456)789)/', '123456789', $matches);
//0 => 456的後面要接 789,但是456不捕獲,所以要抓的是123789。這也是個有問題的句子。

// (?<!
echo preg_match('/(?<!456)123/', '123456789', $matches);
//1 => 456的後面不能是 123,但是456不捕獲,要抓的是123

echo "<pre>";
print_r($matches);
echo "</pre>";

?>
======================================================
參考文章:
淺談PHP業餘玩家-正規表示式
常用的PHP正規表示式 javascript正则表达式
Pattern Modifiers 3-13:正規表示法:表單資料驗證
使用 Regular Expression 驗證密碼:使用 JavaScript 的陷阱 (右合樣 lookahead)
======================================================


同時符合多組關鍵字
規則
/^(?=.*printer)(?=.*network)(?=.*wireless)(?=.*urgent).*$/
測試字串
wtf is wrong with printer wireless network , somebody needs to fix it right now, its urgent, get it? I remember buying it from a store and not craigslist :)
來源:http://www.rubular.com/r/XcVz5xMZcb
參考:Mastering Lookahead and Lookbehind




沒有留言:

張貼留言