php正則表達式教程 (有結合例子)

來源:phpx   作者:未知
首先,向寫這篇文章的GG 或MM表示感謝!

如果你不斷地建立不同的函數來檢查或者操作字符串的一部分,現在你可能要放棄所有的這些函數,取而代之的用正則表達式。如果你對下列的問題都答“是的”,那麼你肯定要考慮使用正則表達式了:

你是否正在寫一些定製的函數來檢查表單數據(比如在電子信箱地址中的一個@,一個點)?
你是否寫一些定製的函數,在一個字符串中循環每個字符,如果這個字符匹配了一個特定特徵(比如它是大寫的,或者它是一個空格),那麼就替換它?
除了是令人不舒服的字符串檢查和操作方法,如果沒有有效率地寫代碼,上述的兩條也會使你的程序慢下來。你是否更傾向於用下面的代碼檢查一個電子信箱地址呢:

<?php
function validateEmail($email)
{
$hasAtSymbol = strpos($email, "@");
$hasDot = strpos($email, ".");
if($hasAtSymbol && $hasDot)
return true;
else
return false;
}
echo validateEmail("[email protected]");
?>
... 或者使用下面的代碼:

<?php
function validateEmail($email)
{
return ereg("^[a-zA-Z]+@[a-zA-Z]+/.[a-zA-Z]+$", $email);
}
echo validateEmail("[email protected]");
?>

可以肯定的是,第一個函數比較容易,而且看起來結構也不錯。但是如果我們用上面的下一個版本的email地址檢查函數不是更容易嗎?

上面展示的第二個函數只用了正則表達式,包括了對ereg函數的一個調用。Ereg 函數返回true或者false,來聲明它的字符串參數是否和正則表達式相匹配。

很多編程者避開正則表達式,只因爲它們(在一些情況下)比其它的文本處理方法更慢。正則表達式可能慢的原因是因爲它們涉及把字符串在內存中拷貝和粘貼,因爲正則表達式的每一個新的部分都對應匹配一個字符串。但是,從我對正則表達式的經驗來說,除非你在文本中幾百個行運行一個複雜的正則表達式,否則性能上的缺陷都可以忽略不計,當把正則表達式作爲輸入數據檢查工具時,也很少出現這種情況。



正則表達式語法
在你可以匹配一個字符串到正則表達式之前,你必須先建立正則表達式。開始的時候,正則表達式的語法有點古怪,表達式中的每一個短語代表某個類型的搜索特徵。下列是一些最普通的正則表達式,也都對應着一個如何使用它的例子:

字符串頭部
搜索一個字符串的頭部,用^,例如

<?php echo ereg("^hello", "hello world!"); ?>
將返回 true, 但是
<?php echo ereg("^hello", "i say hello world"); ?>
將返回 false, 因爲hello不在字符串”I say hello world”的頭部。
字符串尾部

搜索字符串尾部,用$,例如:
<?php echo ereg("bye$", "goodbye"); ?>
將返回true, 但是
<?php echo ereg("bye$", "goodbye my friend"); ?>
將返回 false,因爲bye不在字符串”goodbye my friend”的尾部.

任意的單個字符
搜索任意字符,用點(.),例如:
<?php echo ereg(".", "cat"); ?>
將返回true,但是
<?php echo ereg(".", ""); ?>
將返回false,因爲我們的要搜索字符串沒有包含字符。你可以用花括號隨意告訴正則表達式引擎它要匹配多少個單個字符。如果我只想匹配5個字符,我可以這樣用ereg:
<?php echo ereg(".{5}$", "12345"); ?>
上面的這段代碼告訴正則表達式引擎當且僅當至少5個連續的字符出現字符串的尾部時返回true.我們也可以限制連續出現的字符的數目:
<?php echo ereg("a{1,3}$", "aaa"); ?>
在上面的例子裏,我們已經告訴正則表達式引擎,我們的搜索字符串來匹配表達式,它在尾部必須有介於1和3個的”a”字符。
<?php echo ereg("a{1,3}$", "aaab"); ?>
上面的例子將不會返回true,雖然有三個”a”字符在搜索字符串裏,但是它們不是在字符串的尾部。如果我們把結尾字符串匹配$從正則表達式中去掉,那麼這個字符串是匹配的。
我們也可以告訴正則表達式引擎來匹配至少有確定數目的字符在一行,如果它們存在的,可以匹配更多。 我們可以這樣做:
<?php echo ereg("a{3,}$", "aaaa"); ?>

零或多次重複字符
爲了告訴正則表達式引擎一個字符可能存在,也可以重複,我們用*字符。這裏的兩個例子都將返回true.

<?php echo ereg("t*", "tom"); ?>
<?php echo ereg("t*", "fom"); ?>
即使第二個例子不包含”t”這個字符,但仍舊返回ture,因爲*表示字符可以出現,但不是必須出現。事實上,任何普通的字符串模式都會使上面的ereg調用返回true,因爲’t’字符是可選的.


一或多次重複字符
爲了告訴正則表達式引擎一個字符必須存在,也可以重複不止一次,我們用+字符,像

<?php echo ereg("z+", "i like the zoo"); ?>
下面的例子也會返回true:
<?php echo ereg("z+", "i like the zzzzzzoo!"); ?>

零或一次重複字符
我們也可以告訴正則表達式引擎,一個字符必須是或者只存在一次,或者沒有。我們用?字符來做這項工作,就像
<?php echo ereg("c?", "cats are fuzzy"); ?>
如果我們願意,我們完全可以從上面的搜索字符串中刪除’c’,這個表達式會仍舊返回true.’?’ 的意思是一個’c’可以出現在搜索字符串的任何地方,但不是必須的。


正則表達式語法 (續)
空格字符
爲了匹配一個搜索字符串中的空格字符,我們用預定義Posix的類,[[:space]].方括號標明連續字符的相關性,”:space:”是實際要匹配的類(在這種情形下,是任何空白字符)。空白包括tab字符,新行字符,空白字符。或者,如果搜索字符串必須包含只有一個空格,而不是一個tab或者新行字符,你可以用一個空格字符(" ")。在大多數情況下,我傾向於使用":space:",因爲這意味着我的意圖不僅僅是單個空格字符,這點很容易被忽視。這裏有一些Posix-標準預定義類,
有一些我們可以作爲正則表達式的部分的一些Posix-標準預定義類,包括[:alnum:], [:digit:], [:lower:]等等。 完整的列表可以在這裏查看

我們可以像這樣匹配單個空白字符:

<?php echo ereg("Mitchell[[:space:]]Harper", "Mitchell Harper"); ?>
我們也可以通過在表達式後用?字符來告訴正則表達式引擎匹配沒有空白或者一個空白。
<?php echo ereg("Mitchell[[:space:]]?Harper", "MitchellHarper"); ?>

模式分組
相關的模式可以在方括號裏分在一起。很容易用[a-z]和[A-Z]指定只有一個小寫字母或者一列大寫字母以搜索字符串的一部分存在。
<?php
// 要求從第一個到最後一個都是小寫字母
echo ereg("^[a-z]+$", "johndoe"); // 返回true
?>
或者像
<?php
// 要求從第一個到最後一個都是大寫字母
ereg("^[A-Z]+$", "JOHNDOE"); // 返回 true?
?>
我們也可以告訴正則表達式引擎,我們希望或者是小寫字母,或者是大寫字母。我們只要把[a-z]和[A-Z]模式結合在一起就可以做到。
<?php echo ereg("^[a-zA-Z]+$", "JohnDoe"); ?>
在上面的例子裏,如果我們能匹配"John Doe",而不是"JohnDoe",將是非常有意義的。我們用下面的正則表達式來做這個:
^[a-zA-Z]+[[:space:]]{1}[a-zA-Z]+$
很容易搜索一個數字字符串
<?php echo ereg("^[0-9]+$", "12345"); ?>

詞語分組
不僅僅搜索模式可以分組,我們也可以用圓括號把相關的搜索詞語進行分組。
<?php echo ereg("^(John|Jane).+$", "John Doe"); ?>
在上面的例子中,我們有一個字符串頭部字符,緊跟着"John"或者"Jane",至少有一個其它字符,然後一個字符串尾部字符。所以…
<?php echo ereg("^(John|Jane).+$", "Jane Doe"); ?>
...將也匹配我們的搜索模式

特殊字符的情形
因爲一些字符要用在一個搜索模式的明確分組或者語法上,像在(John|Jane)中的圓括號,我們需要告訴正則表達式引擎來屏蔽這些字符,加工它們使之成爲被搜索字符串的一部分,而不是搜索表達式的一部分。我們所用的方法稱爲“字符轉義”,涉及到將任何“專用符號”加上反斜槓。所以,例如,如果我想在我的搜索中包含’|’,那麼我就可以這樣做
<?php echo ereg("^[a-zA-z]+/|[a-zA-z]+$", "John|Jane"); ?>
這裏只是少量的一些你要轉義的字符,你必須轉義^, $, (, ), ., [, |, *, ?, +, / and { 。
希望你現在對正則表達式實際上有多麼強大有了一點點感覺了。現在讓我們看兩個用正則表達式來檢查數據中一個字符串的例子。


正則表達式例子
例子1
讓我們把第一個例子做的相當簡單,檢驗一個標準的URL.一個標準的URL(沒有端口號),有三個部分構成:

[協議]://[域名]

讓我們從匹配URL的協議部分開始,並且讓它只能用http或者ftp.我們可以用下面的正則表達式做到這點:

^(http|ftp)
^字符特指字符串的頭部,利用圓括號把http和ftp圍住,且用“或者”符號(|)將它們分開,我們告訴正則表達式引擎http和ftp兩者之一必須在字符串的開頭。

一個域名通常由www.somesite.com構成,但是可以隨意選擇要不要www部分。爲了例子簡單,我們只允許.com,.net,和.org的域名是在考慮之中的。我們最好這樣對正則表達式中的域名部分表示如下:
(www/.)?.+/.(com|net|org)$
把所有的東西放在一起,我們的正則表達式就可以用作檢查一個域名,如:

<?php
function isValidDomain($domainName)
{

return ereg("^(http|ftp)://(www/.)?.+/.(com|net|org)$", $domainName);
}
//真(true)
echo isValidDomain("http://www.somesite.com");
//真(true)
echo isValidDomain("ftp://somesite.com");
//假 (false)
echo isValidDomain("ftp://www.somesite.fr");
//假 (false)
echo isValidDomain("www.somesite.com");
?>

例子二
因爲我居住在澳大利亞悉尼,讓我們檢查一個典型的澳大利亞國際電話號碼。澳大利亞國際電話號碼的格式如下:
+61x xxxx-xxxx
第一個x是區號,其它的都是電話號碼。檢查以'+61'開頭且緊跟一個在2到9之間的區號的電話號碼,我們用下面的正則表達式:

^/+61[2-9][[:space:]]
注意,上面的搜索模式把'+'字符用''轉義,以便於可以在搜索中包含,不至於被解釋爲一個正則表達式。[2-9]告訴正則表達式引擎我們需要包含一個2到9之間的數字。[[:space:]]類則告訴正則表達式期望在這裏有一個空白。

這裏是電話號碼剩下的搜索模式:
[0-9]{4}-[0-9]{4}$
這裏沒有什麼不尋常的地方,我們只是告訴正則表達式引擎電話號碼可用的數字,它必須是4個數字的組合,跟着一個連接符,再跟着另一個4個數字的組合,然後一個字符串尾部字符。
把完整的正則表達式放在一起,放進一個函數,我們可以用代碼來檢查一些澳大利亞國際電話號碼:
<?php
function isValidPhone($phoneNum)
{
echo ereg("^/+61[2-9][[:space:]][0-9]{4}-[0-9]{4}$", $phoneNum);
}
// 真(true)
echo isValidPhone("+619 0000-0000");
// 假(false)
echo isValidPhone("+61 00000000");
//假( false)
echo isValidPhone("+611 00000000");
?>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章