最近更新: 2006-11-15

Let results of preg_match be an associative array

在 Regular Expression (REGEX) 的語法中,有一種方式可以讓我們將 subpatterns 的內容存放在一個數值索引陣列,而以 $1, $2, $3, ... (或 \1, \2, \3, ...) 的敘述方式取用。雖然這已經很方便了,但仍然有缺點,就是比對結果不易理解,時日一久,很容易忘記 $1, $2,... 各是代表什麼意思。所以 PHP 在 4.3.3 版之後增加了一個新語法,可以指派名稱給 subpattern ,這個語法格式是: (?P<name>pattern) 。如此一來就可以將 subpatterns 的內容存放在一個關聯陣列 (associative array) 中,可以鍵值取用,提高程式可讀性。

對於 Regular expression 基本語法,我假設讀者已經熟悉了,不做細部說明。

Example of preg_match()

以 HTML 中的 input 標籤為例,將 input 標籤中的 name 和 value 屬性的值比對出來,並利用為 subpattern 命名的語法,令 preg_match() 產生一個有鍵值 'name' 和 'value' 的關聯陣列。

<?php
$s = <<<PAGE
<input class="textBox" type="text" name="userName" value="abc" />
PAGE;

preg_match('/<input[^>]+name="(?P<name>[^"]+)"[^>]+value="(?P<value>[^"]*)"[^>]*>/', $s, $field);
print_r($field);

echo $field['name'], ' = ', $field['value'];
  
?>

Example of preg_match_all()

以 HTML 的表單元素為例,將其中 input 和 textarea 元素的 name 與 value 屬性的值分別比對出來,最後利用陣列函數,將結果合併成為一個對應表單內容之 key => value 的關聯陣列。

<?php
$loadPage = <<<PAGE
<form>
    <label>Name:
        <input class="textBox" type="text" name="userName" value="abc" />
    </label><br/>
    <labe>Phone:
        <input type="text" name="userPhone" value="123456" readonly="readonly"/>
    </label><br/>
    <label>Address:
        <input name="userAddress" type="text" value="ROC"/>
    </label><br/>
    <text_area name="Note">hello world. Today is monday.</text_area>
</form>
PAGE;
// 1. fetch field putting in input
preg_match_all('/<input[^>]+name="(?P<name>[^"]+)"[^>]+value="(?P<value>[^"]*)"[^>]*>/', $loadPage, $matches1);
print_r($matches1);

// 2. fetch field putting in textarea
preg_match_all('/<(textarea)[^>]+name="(?P<name>[^"]+)"[^>]*>(?P<value>.*)<\/\1>/', $loadPage, $matches2);
print_r($matches2);

$fields = array_combine(
    array_merge($matches1['name'], $matches2['name']),
    array_merge($matches1['value'], $matches2['value'])
);
print_r($fields);

foreach ($fields as $k => $v) {
    echo 'Value of field ', $k, ' is ', $v, ".\n";
}

?>

我常常將這種技巧用在 JSP 或 ASP.Net 產生的網頁內容上,那些網頁常常使用 WebUI 控制項來顯示網頁內容,因此網頁有大量表單元素 (input, textarea, hidden, select, ...) ,這些元素都包含 'name' 和 'value' 屬性。要從中取出這些 name 和 value 的內容,正規做法應該是用 PHP 的 DOM functions ,但我覺得太麻煩,而效能也是一個考量因素,因此我通常選擇使用 PCRE functions 將那些內容「比對」出來,利用指派名稱給 subpattern 的擴充語法,就更敏捷了。

相關文章
樂多舊網址: http://blog.roodo.com/rocksaying/archives/2480607.html