熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> PHP編程 >> 正文

PHP和正則表達式

2013-11-15 12:39:00  來源: PHP編程 
  一個正則表達式是一個特定的格式化模式可以用來找出一個字符串在另一個字符串中的使用情況幾個編程語言包括Visual BasicPerlJavaScript和PHP都支持正則表達式希望在這篇入門指導的結束Mitchell(作者自己)可以讓你在PHP程序中能應用一些基本的正則表達式正則表達式是在各種各樣的程序語言中突出的古怪特征中的一種但是由於它們看起來是很難的一個概念所以很多開發者就把它們放到了角落裡忘記了它們的存在


  讓我們先來看看什麼是正則表達式為什麼你要在PHP程序中用到它們

  什麼是正則表達式?

  你對從一個不錯的老的基於控制的文本編輯器中分離出像BBEdit和notepad的程序有什麼看法呢?兩個都支持文本輸入可以讓你保存文本到文件中但是現在的文本編輯器也支持其它功能包括查找–代替工具這讓編輯一個文本文件相當容易

  正則表達式也是相似的只是更好一些正則表達式可以被認為是一個極其高級的查找替換工具讓我們從痛苦中擺脫出來不必再寫定制的數據確認例子來檢查電子郵件地址或者來確認電話號碼的格式是正確的如此等等

  任何程序中最普通的函數之一就是數據有效性檢查PHP捆綁了一些文本檢查函數允許我們用正則表達式匹配一個字符串確認有一個空格有一個問號等等

  你不知道的可能是正則表達式可以簡單裝備嗎當你掌握了一些正則表達式時(這個正則表達式可以用來告訴正則表達式引擎一個字符串中我們想要匹配的部分)你會自問為什麼會把正則表達式扔到角落裡這麼久^_^

  PHP有兩套函數用來處理兩種類型的正則表達式:Perl兼容模式和Posix標准兼容模式

  在這篇文章中我們將看看ereg函數用遵照Posix標准的搜索表達式工作雖然它們並沒有Perl模式那樣強大但是一種不錯的學習正則表達式的方法如果你對PHP支持的Perl兼容正則表達式感興趣可以到PHPnet網站找一些關於preg函數的細節

  PHP有六個函數來處理正則表達式它們都把一個正則表達式作為它們的第一個參數列出如下

ereg: 最常用的正則表達式函數 ereg 允許我們搜索跟一個正則表達式匹配的一個字符串

ereg_replace: 允許我們搜索跟正則表達式匹配的一個字符串並用新的字符串代替所有這個表達式出現的地方

eregi: 和ereg幾乎是一樣效果不過忽略大小寫

eregi_replace: 和ereg_replace有著一樣的搜索替換功能不過忽略大小寫

split: 允許我們搜索和正則表達式匹配的字符串並且以字符串集合的方式返回匹配結果

spliti: split函數忽略大小寫的版本

  為什麼使用正則表達式?

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

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

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

<?php
function validateEmail($email)
{
return ereg(^[azAZ]+@[azAZ]+\[azAZ]+$ $email);
}
echo validateEmail(mitchell@devarticlescom);
?>

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

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

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

  正則表達式語法

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

  1字符串頭部

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

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

  2字符串尾部

  搜索字符串尾部用$例如

<?php echo ereg(bye$ goodbye); ?>
將返回true 但是
<?php echo ereg(bye$ goodbye my friend); ?>
將返回 false因為bye不在字符串goodbye my friend的尾部

  3任意的單個字符

  搜索任意字符用點()例如

<?php echo ereg( cat); ?>
將返回true但是
<?php echo ereg( ); ?>
將返回false因為我們的要搜索字符串沒有包含字符你可以用花括號隨意告訴正則表達式引擎它要匹配多少個單個字符

  如果我只想匹配個字符我可以這樣用ereg:
<?php echo ereg({}$ ); ?>

  上面的這段代碼告訴正則表達式引擎當且僅當至少個連續的字符出現字符串的尾部時返回true我們也可以限制連續出現的字符的數目

<?php echo ereg(a{}$ aaa); ?>

  在上面的例子裡我們已經告訴正則表達式引擎我們的搜索字符串來匹配表達式它在尾部必須有介於個的a字符

<?php echo ereg(a{}$ aaab); ?>

  上面的例子將不會返回true雖然有三個a字符在搜索字符串裡但是它們不是在字符串的尾部如果我們把結尾字符串匹配$從正則表達式中去掉那麼這個字符串是匹配的

  我們也可以告訴正則表達式引擎來匹配至少有確定數目的字符在一行如果它們存在的可以匹配更多 我們可以這樣做
<?php echo ereg(a{}$ aaaa); ?>

  4零或多次重復字符

  為了告訴正則表達式引擎一個字符可能存在也可以重復我們用*字符這裡的兩個例子都將返回true

<?php echo ereg(t* tom); ?>
<?php echo ereg(t* fom); ?>

  即使第二個例子不包含t這個字符但仍舊返回ture因為*表示字符可以出現但不是必須出現事實上任何普通的字符串模式都會使上面的ereg調用返回true因為t字符是可選的


  5一或多次重復字符

  為了告訴正則表達式引擎一個字符必須存在也可以重復不止一次我們用+字符像<?php echo ereg(z+ i like the zoo); ?>

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

  6零或一次重復字符

  我們也可以告訴正則表達式引擎一個字符必須是或者只存在一次或者沒有我們用?字符來做這項工作就像
<?php echo ereg(c? cats are fuzzy); ?>

  如果我們願意我們完全可以從上面的搜索字符串中刪除c這個表達式會仍舊返回true? 的意思是一個c可以出現在搜索字符串的任何地方但不是必須的

  7空格字符

  為了匹配一個搜索字符串中的空格字符我們用預定義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); ?>

  8模式分組

  相關的模式可以在方括號裡分在一起很容易用[az]和[AZ]指定只有一個小寫字母或者一列大寫字母以搜索字符串的一部分存在

<?php
// 要求從第一個到最後一個都是小寫字母
echo ereg(^[az]+$ johndoe); // 返回true
?>

  或者像

<?php
// 要求從第一個到最後一個都是大寫字母
ereg(^[AZ]+$ JOHNDOE); // 返回 true?
?>

  我們也可以告訴正則表達式引擎我們希望或者是小寫字母或者是大寫字母我們只要把[az]和[AZ]模式結合在一起就可以做到

<?php echo ereg(^[azAZ]+$ JohnDoe); ?>

  在上面的例子裡如果我們能匹配John Doe而不是JohnDoe將是非常有意義的我們用下面的正則表達式來做這個
^[azAZ]+[[:space:]]{}[azAZ]+$

很容易搜索一個數字字符串
<?php echo ereg(^[]+$ ); ?>

  9詞語分組

  不僅僅搜索模式可以分組我們也可以用圓括號把相關的搜索詞語進行分組

<?php echo ereg(^(John|Jane)+$ John Doe); ?>

  在上面的例子中我們有一個字符串頭部字符緊跟著John或者Jane至少有一個其它字符然後一個字符串尾部字符所以…

<?php echo ereg(^(John|Jane)+$ Jane Doe); ?>
將也匹配我們的搜索模式

  10特殊字符的情形

  因為一些字符要用在一個搜索模式的明確分組或者語法上像在(John|Jane)中的圓括號我們需要告訴正則表達式引擎來屏蔽這些字符加工它們使之成為被搜索字符串的一部分而不是搜索表達式的一部分我們所用的方法稱為字符轉義涉及到將任何專用符號加上反斜槓所以例如如果我想在我的搜索中包含|那麼我就可以這樣做
<?php echo ereg(^[azAz]+\|[azAz]+$ John|Jane); ?>

  這裡只是少量的一些你要轉義的字符你必須轉義^ $ ( ) [ | * ? + \ and {

  正則表達式例子

  希望你現在對正則表達式實際上有多麼強大有了一點點感覺了現在讓我們看兩個用正則表達式來檢查數據中一個字符串的例子

例子一

  讓我們把第一個例子做的相當簡單檢驗一個標准的URL一個標准的URL(沒有端口號)有三個部分構成

  [協議]://[域名]

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

  ^(http|ftp)

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

  一個域名通常由wwwsomesitecom構成但是可以隨意選擇要不要www部分為了例子簡單我們只允許comnetorg的域名是在考慮之中的我們最好這樣對正則表達式中的域名部分表示如下
(www\)?+\(com|net|org)$

  把所有的東西放在一起我們的正則表達式就可以用作檢查一個域名

<?php
function isValidDomain($domainName)
{

return ereg(^(http|ftp)://(www\)?+\(com|net|org)$ $domainName);
}
//真(true)
echo isValidDomain(http://wwwsomesitecom);
//真(true)
echo isValidDomain(ftp://somesitecom);
//假 (false)
echo isValidDomain(ftp://wwwsomesitefr);
//假 (false)
echo isValidDomain(wwwsomesitecom);
?>

例子二

  因為我居住在澳大利亞悉尼讓我們檢查一個典型的澳大利亞國際電話號碼澳大利亞國際電話號碼的格式如下
  +x xxxxxxxx

  第一個x是區號其它的都是電話號碼檢查以+開頭且緊跟一個在之間的區號的電話號碼我們用下面的正則表達式
   ^\+[][[:space:]]

  注意上面的搜索模式把+字符用\轉義以便於可以在搜索中包含不至於被解釋為一個正則表達式[]告訴正則表達式引擎我們需要包含一個之間的數字[[:space:]]類則告訴正則表達式期望在這裡有一個空白

  這裡是電話號碼剩下的搜索模式
  []{}[]{}$

  這裡沒有什麼不尋常的地方我們只是告訴正則表達式引擎電話號碼可用的數字它必須是個數字的組合跟著一個連接符再跟著另一個個數字的組合然後一個字符串尾部字符
把完整的正則表達式放在一起放進一個函數我們可以用代碼來檢查一些澳大利亞國際電話號碼

<?php
function isValidPhone($phoneNum)
{
echo ereg(^\+[][[:space:]][]{}[]{}$ $phoneNum);
}
// 真(true)
echo isValidPhone(+ );
// 假(false)
echo isValidPhone(+ );
//假( false)
echo isValidPhone(+ );
?>

  總結

  正則表達式用一些不適合書寫和重復的代碼來檢查一個字符串我們已經講解了所有的Posix標准正則表達式的基礎包括字符分組和PHP ereg函數我們也知道了怎麼用正則表達式來檢查一些PHP中簡單的字符串

  譯者注釋本人英文不怎麼好可能一些地方有出入本文中的字符類其實是我們所說的字符簇


From:http://tw.wingwit.com/Article/program/PHP/201311/21350.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.