int preg_match_all ( string pattern, string subject, array matches [, int flags])
在 subject 中搜索所有與 pattern 給出的正則表達式匹配的內容并將結果以 flags 指定的順序放到 matches 中.
搜索到第一個匹配項之后,接下來的搜索從上一個匹配項末尾開始.
flags 可以是下列標記的組合(注意把 PREG_PATTERN_ORDER 和 PREG_SET_ORDER 合起來用沒有意義).
PREG_PATTERN_ORDER
對結果排序使 $matches[0] 為全部模式匹配的數組,$matches[1] 為第一個括號中的子模式所匹配的字符串組成的數組,以此類推,代碼如下:
- <?php
- preg_match_all ("|<[^>]+>(.*)</[^>]+>|U",
- "<b>example: </b><div align=left>this is a test</div>",
- $out, PREG_PATTERN_ORDER);
- print $out[0][0].", ".$out[0][1]."/n";
- print $out[1][0].", ".$out[1][1]."/n";
- ?>
- //本例將輸出:
- <b>example: </b>, this is a test example: , this is a test
因此,$out[0] 包含匹配整個模式的字符串,$out[1] 包含一對 HTML 標記之間的字符串.
對結果排序使 $matches[0] 為全部模式匹配的數組,$matches[1] 為第一個括號中的子模式所匹配的字符串組成的數組,以此類推。(即$matches[0] [0]為全部模式匹配中的每一項,$matches[0] [1]為全部模式匹配中的第二項,$matches[1] [0]為匹配每一個括號中的第一項,$matches[1] [0]為匹配每一個括號中的第二項),代碼如下:
- <?php
- preg_match_all ("|<[^>]+>(.*)</[^>]+>|U",
- "<b>example: </b><div align=left>this is a test</div>",
- $out, PREG_PATTERN_ORDER);
- print $out[0][0].", ".$out[0][1]."n";
- print $out[1][0].", ".$out[1][1]."n";
- ?>
- //本例將輸出:
- <b>example: </b>, <div align=left>this is a test</div>
- example: , this is a test
因此,$out[0] 包含匹配整個模式的字符串,$out[1] 包含一對 HTML 標記之間的字符串.
如果使用PREG_SET_ORDER
對結果排序使 $matches[0] 為第一組匹配項的數組,$matches[1] 為第二組匹配項的數組,以此類推。(即$matches[0] [0]為第一組匹配項中完整匹配的字符串,$matches[0] [1]為第一組匹配中完整匹配第一個括號中的字符串),代碼如下:
- <?php
- preg_match_all ("|<[^>]+>(.*)</[^>]+>|U",
- "<b>example: </b><div align=left>this is a test</div>",
- $out, PREG_SET_ORDER);
- print $out[0][0].", ".$out[0][1]."n";
- print $out[1][0].", ".$out[1][1]."n";
- ?>
- //本例將輸出:
- //<b>example: </b>, example:
- //<div align=left>this is a test</div>, this is a test
本例中,$matches[0] 是第一組匹配結果,$matches[0][0] 包含匹配整個模式的文本,$matches[0][1] 包含匹配第一個子模式的文本,以此類推。同樣,$matches[1] 是第二組匹配結果,等等。
PREG_OFFSET_CAPTURE
如果設定本標記,對每個出現的匹配結果也同時返回其附屬的字符串偏移量。注意這改變了返回的數組的值,使其中的每個單元也是一個數組,其中第一項為匹配字符串,第二項為其在 subject 中的偏移量。本標記自 PHP 4.3.0 起可用。
如果沒有給出標記,則假定為 PREG_PATTERN_ORDER
返回整個模式匹配的次數(可能為零),如果出錯返回 FALSE。
例子 1.從某文本中取得所有的電話號碼,代碼如下:
- <?php
- preg_match_all ("/(? (d)? )? (?(1) [-s] ) d-d/x",
- "Call 555-1212 or 1-800-555-1212", $phones);
- ?>
例子 2.搜索匹配的 HTML 標記(greedy),代碼如下:
- <?php
- // /2 是一個逆向引用的例子,其在 PCRE 中的含義是
- // 必須匹配正則表達式本身中第二組括號內的內容,本例中
- // 就是 ([w]+)。因為字符串在雙引號中,所以需要
- // 多加一個反斜線。
- $html = "<b>bold text</b><a href=howdy.html>click me</a>";
- preg_match_all ("/(<([w]+)[^>]*>)(.*)(<//2>)/", $html, $matches);
- for ($i=0; $i< count($matches[0]); $i++) {
- echo "matched: ".$matches[0][$i]."n";
- echo "part 1: ".$matches[1][$i]."n";
- echo "part 2: ".$matches[3][$i]."n";
- echo "part 3: ".$matches[4][$i]."nn";
- }
- ?>
- 本例將輸出:
- matched: <b>bold text</b>
- part 1: <b>
- part 2: bold text
- part 3: </b>
- matched: <a href=howdy.html>click me</a>
- part 1: <a href=howdy.html>
- part 2: click me
- part 3: </a>
例3. 在文本中搜索“php”,代碼如下:
- <?php
- // 模式定界符后面de “i” 表示不區分大小寫字母de搜索
- 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.”;
- }
- ?>
例4. 搜索單詞“web”,代碼如下:
- <?php
- /* 模式中de b 表示單詞de邊界,因此只you獨立de “web” 單詞會被匹配,
- * 而不會匹配例如 “webbing” 或 “cobweb” 中de一部分 */
- if (preg_match (“/bwebb/i”, “PHP is the web scripting language of choice.”)) {
- print “A match was found.”;
- } else {
- print “A match was not found.”;
- }
- if (preg_match (“/bwebb/i”, “PHP is the website scripting language of choice.”)) {
- print “A match was found.”;
- } else {
- print “A match was not found.”;
- }
- ?>
例5. 從 URL 中取出域名,代碼如下:
- <?php
- // 從 URL 中取得主機名
- preg_match(“/^(http://)?([^/]+)/i”,
- $host = $matches.;
- // 從主機名中取得后面兩段
- preg_match(“/[^./]+.[^./]+$/”, $host, $matches);
- echo “domain name is: {$matches[0]}n”;
- ?>
- //輸出:
- //domain name is: php.net
preg_match_all 導致apache 重啟的解決辦法
如 preg_match_all("/ni(.*?)wo/", $html, $matches);)進行分析匹配比較長的字符串 $html 時(大于10萬字節,一般用于分析采集回來的網頁源碼),Apache服務器會崩潰自動重啟。
在Apache錯誤日志里有這樣的提示:
- [Thu Apr 11 18:31:31 2013] [notice] Parent: child process exited with status 128 -- Restarting.
- [Thu Apr 11 18:31:31 2013] [notice] Apache/2.2.9 (Win32) PHP/5.2.17 configured -- resuming normal operations
- [Thu Apr 11 18:31:31 2013] [notice] Server built: Jun 13 2008 04:04:59
- [Thu Apr 11 18:31:31 2013] [notice] Parent: Created child process 2964
- [Thu Apr 11 18:31:31 2013] [notice] Disabled use of AcceptEx() WinSock2 API
- [Thu Apr 11 18:31:31 2013] [notice] Child 2964: Child process is running
- [Thu Apr 11 18:31:31 2013] [notice] Child 2964: Acquired the start mutex.
- [Thu Apr 11 18:31:31 2013] [notice] Child 2964: Starting 350 worker threads.
- [Thu Apr 11 18:31:31 2013] [notice] Child 2964: Listening on port 80.
那么如何增加win平臺下 ThreadStackSize 的大小呢? 在apache的配置文件 httpd.conf 里啟用 “Include conf/extra/httpd-mpm.conf”(刪除前面的注釋#),然后在 httpd-mpm.conf 文件里的 mpm_winnt_module 配置模塊里設置 “ThreadStackSize 8400000”即可(大約8M),代碼如下:
- <IfModule mpm_winnt_module>
- ThreadStackSize 8400000
- ThreadsPerChild 200
- MaxRequestsPerChild 10000
- Win32DisableAcceptEx
- </IfModule>
這里需要注意的是,32位的Apache程序只能最多使用大約2GB內存空間,因此,ThreadStackSize 和ThreadsPerChild 的值相乘后(8M * 200)不應該超過2G,否則無法啟動apache,出現的錯誤日志如下:
通過上面的提示,飄易可以告訴大家的是在我的這臺服務器上,當線程堆棧大小設為8M時,我可以設置的線程數最多是212個.
新聞熱點
疑難解答