首先來看看 POSIX 風格Regex的兩個主要函數:
ereg 函數:(Regex匹配)
格式:int ereg ( string pattern, string string [, array ®s] )
注意:使用 Perl 相容Regex文法的 preg_match() 函數通常是比 ereg() 更快的替代方案。(一般的話還是使用 preg_match() ,比較好勒~~)
以區分大小寫方式在 string 中尋找與給定的Regex pattern 所匹配的子串。如果找到與 pattern 中圓括弧內的子模式相匹配的子串並且函數調用給出了第三個參數 regs,則匹配項將被存入 regs 數組中。$regs[1] 包含第一個左圓括弧開始的子串,$regs[2] 包含第二個子串,以此類推。$regs[0] 包含整個匹配的字串。
傳回值:如果在 string 中找到 pattern 模式的匹配則返回 所匹配字串的長度,如果沒有找到匹配或出錯則返回 FALSE。如果沒有傳遞入選擇性參數 regs 或者所匹配的字串長度為 0,則本函數返回 1。
來看看 ereg() 函數的例子:
以下代碼片斷接受 ISO 格式的日期(YYYY-MM-DD)然後以 DD.MM.YYYY 格式顯示:
複製代碼 代碼如下:
<?php
if (ereg ("([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})", $date, $regs)) {
echo "$regs[3].$regs[2].$regs[1]";
} else {
echo "Invalid date format: $date";
}
?>
-----------------------------------------------------------------------------------
ereg_replace 函數:(Regex替換)
格式:string ereg_replace ( string pattern, string replacement, string string )
函數說明:
本函數在 string 中掃描與 pattern 匹配的部分,並將其替換為 replacement。
返回替換後的字串。(如果沒有可供替換的匹配項則會返回原字串。)
如果 pattern 包含有括弧內的子串,則 replacement 可以包含形如 \\digit 的子串,這些子串將被替換為數字表示的第幾個括弧內的子串;\\0 則包含了字串的整個內容。最多可以用九個子串。括弧可以嵌套,此情形下以左圓括弧來計算順序。
如果未在 string 中找到匹配項,則 string 將原樣返回。
來看看這個函數例子吧:
1,下面的代碼片斷輸出 "This was a test" 三次:
複製代碼 代碼如下:
<?php
$string = "This is a test";
echo str_replace(" is", " was", $string);
echo ereg_replace("( )is", "\\1was", $string);
echo ereg_replace("(( )is)", "\\2was", $string);
?>
要注意的一點是如果在 replacement 參數中使用了整數值,則可能得不到所期望的結果。這是因為ereg_replace() 將把數字作為字元的序列值來解釋並應用之。例如:
2,replacement 參數為整數時的例子:
複製代碼 代碼如下:
<?php
/* 不能產生出期望的結果 */
$num = 4;
$string = "This string has four words.";
$string = ereg_replace('four', $num, $string);
echo $string; /* Output: 'This string has words.' */
/* 本例工作正常 */
$num = '4';
$string = "This string has four words.";
$string = ereg_replace('four', $num, $string);
echo $string; /* Output: 'This string has 4 words.' */
?>
3,將 URL 替換為超連結:
複製代碼 代碼如下:
$text = ereg_replace("[[:alpha:]]+://[^<>[:space:]]+[[:alnum:]/]",
"<a href=\"\\0\">\\0</a>", $text);
提示: preg_replace() 函數使用了 Perl 相容Regex文法,通常是比 ereg_replace() 更快的替代方案。
再來看看 Perl 相容Regex的兩個主要函數:
preg_match 函數:(進行Regex匹配)
格式:int preg_match ( string pattern, string subject [, array matches [, int flags]] )
函數說明:
在 subject 字串中搜尋與 pattern 給出的Regex相匹配的內容。
如果提供了 matches,則其會被搜尋的結果所填充。$matches[0] 將包含與整個模式比對的文本,$matches[1] 將包含與第一個捕獲的括弧中的子模式所匹配的文本,以此類推。
flags 可以是下列標記:
PREG_OFFSET_CAPTURE
如果設定本標記,對每個出現的匹配結果也同時返回其附屬的字串位移量。注意這改變了返回的數組的值,使其中的每個單元也是一個數組,其中第一項為匹配字串,第二項為其位移量。本標記自 PHP 4.3.0 起可用。
flags 參數自 PHP 4.3.0 起可用。
preg_match() 返回 pattern 所匹配的次數。要麼是 0 次(沒有匹配)或 1 次,因為 preg_match() 在第一次匹配之後將停止搜尋。preg_match_all() 則相反,會一直搜尋到 subject 的結尾處。如果出錯 preg_match() 返回 FALSE。
Tips: 如果只想查看一個字串是否包含在另一個字串中,不要用 preg_match()。可以用 strpos() 或 strstr() 替代,要快得多。
來看看它的例子吧:
例 1. 在文本中搜尋“php”:
複製代碼 代碼如下:
<?php
// 模式定界符後面的 "i" 表示不區分大小寫字母的搜尋
if (preg_match ("/php/i", "PHP is the web scripting language of choice.")) {
print "A match was found.";
} else {
print "A match was not found.";
}
?>
例 2. 搜尋單詞“web”:
複製代碼 代碼如下:
<?php
/* 模式中的 \b 表示單詞的邊界,因此只有獨立的 "web" 單詞會被匹配,
* 而不會匹配例如 "webbing" 或 "cobweb" 中的一部分 */
if (preg_match ("/\bweb\b/i", "PHP is the web scripting language of choice.")) {
print "A match was found.";
} else {
print "A match was not found.";
}
if (preg_match ("/\bweb\b/i", "PHP is the website scripting language of choice.")) {
print "A match was found.";
} else {
print "A match was not found.";
}
?>
例 3. 從 URL 中取出網域名稱:
複製代碼 代碼如下:
<?php
// 從 URL 中取得主機名稱
preg_match("/^(http:\/\/)?([^\/]+)/i",
"http://www.php.net/index.html", $matches);
$host = $matches[2];
// 從主機名稱中取得後面兩段
preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches);
echo "domain name is: {$matches[0]}\n";
?>
本例將輸出:
domain name is: php.net
-----------------------------------------------------------------------------------
preg_replace 函數:(執行Regex的搜尋和替換)
格式:mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit] )
函數說明:
在 subject 中搜尋 pattern 模式的匹配項並替換為 replacement。如果指定了 limit,則僅替換 limit 個匹配,如果省略 limit 或者其值為 -1,則所有的匹配項都會被替換。
replacement 可以包含 \\n 形式或(自 PHP 4.0.4 起)$n 形式的逆向引用,首選使用後者。每個此種引用將被替換為與第 n 個被捕獲的括弧內的子模式所匹配的文本。n 可以從 0 到 99,其中 \\0 或 $0 指的是被整個模式所匹配的文本。對左圓括弧從左至右計數(從 1 開始)以取得子模式的數目。
對替換模式在一個逆向引用後面緊接著一個數字時(即:緊接在一個匹配的模式後面的數字),不能使用熟悉的 \\1 符號來表示逆向引用。舉例說 \\11,將會使 preg_replace() 搞不清楚是想要一個 \\1 的逆向引用後面跟著一個數字 1 還是一個 \\11 的逆向引用。本例中的解決方案是使用 \${1}1。這會形成一個隔離的 $1 逆向引用,而使另一個 1 只是單純的文字。
來看看它的例子:
例 1. 逆向引用後面緊接著數位用法:
複製代碼 代碼如下:
<?php
$string = "April 15, 2003";
$pattern = "/(\w+) (\d+), (\d+)/i";
$replacement = "\${1}1,\$3";
print preg_replace($pattern, $replacement, $string);
/* Output
======
April1,2003
*/
?>
如果搜尋到匹配項,則會返回被替換後的 subject,否則返回原來不變的 subject。
preg_replace() 的每個參數(除了 limit)都可以是一個數組。如果 pattern 和 replacement 都是數組,將以其鍵名在數組中出現的順序來進行處理。這不一定和索引的數字順序相同。如果使用索引來標識哪個 pattern 將被哪個 replacement 來替換,應該在調用 preg_replace() 之前用 ksort() 對數組進行排序。
例 2. 在 preg_replace() 中使用索引數組:
複製代碼 代碼如下:
<?php
$string = "The quick brown fox jumped over the lazy dog.";
$patterns[0] = "/quick/";
$patterns[1] = "/brown/";
$patterns[2] = "/fox/";
$replacements[2] = "bear";
$replacements[1] = "black";
$replacements[0] = "slow";
print preg_replace($patterns, $replacements, $string);
/* Output
======
The bear black slow jumped over the lazy dog.
*/
/* By ksorting patterns and replacements,
we should get what we wanted. */
ksort($patterns);
ksort($replacements);
print preg_replace($patterns, $replacements, $string);
/* Output
======
The slow black bear jumped over the lazy dog.
*/
?>
如果 subject 是個數組,則會對 subject 中的每個項目執行搜尋和替換,並返回一個數組。
如果 pattern 和 replacement 都是數組,則 preg_replace() 會依次從中分別取出值來對 subject 進行搜尋和替換。如果 replacement 中的值比 pattern 中的少,則用Null 字元串作為餘下的替換值。如果 pattern 是數組而 replacement 是字串,則對 pattern 中的每個值都用此字串作為替換值。反過來則沒有意義了。
/e 修正符使 preg_replace() 將 replacement 參數當作 PHP 代碼(在適當的逆向引用替換完之後)。提示:要確保 replacement 構成一個合法的 PHP 代碼字串,否則 PHP 會在報告在包含 preg_replace() 的行中出現文法解析錯誤。
例 3. 替換數個值:
複製代碼 代碼如下:
<?php
$patterns = array ("/(19|20)(\d{2})-(\d{1,2})-(\d{1,2})/",
"/^\s*{(\w+)}\s*=/");
$replace = array ("\\3/\\4/\\1\\2", "$\\1 =");
print preg_replace ($patterns, $replace, "{startDate} = 1999-5-27");
?>
本例將輸出:
$startDate = 5/27/1999
例 4. 使用 /e 修正符:
複製代碼 代碼如下:
<?php
preg_replace ("/(<\/?)(\w+)([^>]*>)/e",
"'\\1'.strtoupper('\\2').'\\3'",
$html_body);
?>
這將使輸入字串中的所有 HTML 標籤變成大寫。
例 5. 將 HTML 轉換成文本:
複製代碼 代碼如下:
<?php
// $document 應包含一個 HTML 文檔。
// 本例將去掉 HTML 標籤,javascript 代碼
// 和空白字元。還會將一些通用的
// HTML 實體轉換成相應的文本。
$search = array ("'<script[^>]*?>.*?</script>'si", // 去掉 javascript
"'<[\/\!]*?[^<>]*?>'si", // 去掉 HTML 標籤
"'([\r\n])[\s]+'", // 去掉空白字元
"'&(quot|#34);'i", // 替換 HTML 實體
"'&(amp|#38);'i",
"'&(lt|#60);'i",
"'&(gt|#62);'i",
"'&(nbsp|#160);'i",
"'&(iexcl|#161);'i",
"'&(cent|#162);'i",
"'&(pound|#163);'i",
"'&(copy|#169);'i",
"'&#(\d+);'e"); // 作為 PHP 代碼運行
$replace = array ("",
"",
"\\1",
"\"",
"&",
"<",
">",
" ",
chr(161),
chr(162),
chr(163),
chr(169),
"chr(\\1)");
$text = preg_replace ($search, $replace, $document);
?>
The End…