2011-04-03 23:25:23 4 评论 PHP Boy.Lee

PHP 正则表达式函数库(Perl 兼容)

选自PHP手册

 

介绍

本类函数中所使用的模式极其类似 Perl。表达式应被包含在定界符中,如斜线(/)。任何不是字母、数字或反斜线(\)的字符都可以作为定界符。如果作为定界符的字符必须被用在表达式本身中,则需要用反斜线转义。自 PHP 4.0.4 起,也可以使用 Perl 风格的 (),{},[] 和 <> 匹配定界符。

结束定界符后可以跟上不同的修正符以影响匹配方式。

预定义常量

由于这些常量是由该扩展模块定义的,因此只有在该扩展模块被编译到 PHP 中,或者在运行时被动态加载后,这些常量才有效。

表格 1. PREG 常量

常量 说明
PREG_PATTERN_ORDER 对结果排序使得 $matches[0] 为整个模式的匹配结果的数组,$matches[1] 为第一个括号内的子模式所匹配的字符串的数组,等等。本标记仅用于 preg_match_all()
PREG_SET_ORDER 对结果排序使得 $matches[0] 为第一组匹配结果的数组,$matches[1] 为第二组匹配结果的数组,等等。本标记仅用于 preg_match_all()
PREG_OFFSET_CAPTURE 见 PREG_SPLIT_OFFSET_CAPTURE 的说明。本标记自 PHP 4.3.0 起可用。
PREG_SPLIT_NO_EMPTY 本标记使 preg_split() 仅返回非空的结果。
PREG_SPLIT_DELIM_CAPTURE 本标记使 preg_split() 也捕获定界符模式中的括号表达。本标记自 PHP 4.0.5 起可用。
PREG_SPLIT_OFFSET_CAPTURE 如果设定本标记,对每个出现的匹配结果也同时返回其附属的字符串偏移量。注意这改变了返回的数组的值,使其中的每个单元也是一个数组,其中第一项为匹配字符串,第二项为其偏移量。本标记自 PHP 4.3.0 起可用且仅用于 preg_split()

范例

例子 1. 合法的模式举例
  • /<\/\w+>/

  • |(\d{3})-\d+|Sm

  • /^(?i)php[34]/

  • {^\s+(\s+)?$}

例子 2. 非法的模式举例

  • /href='(.*)' - 缺少结束定界符

  • /\w+\s*\w+/J - 未知的修正符 'J'

  • 1-\d3-\d3-\d4| - 缺少起始定界符

preg_grep

(PHP 4 )

preg_grep --  返回与模式匹配的数组单元

说明

array preg_grep ( string pattern, array input)

preg_grep() 返回一个数组,其中包括了 input 数组中与给定的 pattern 模式相匹配的单元。

自 PHP 4.0.4 起,preg_grep() 返回的结果使用从输入数组来的键名进行索引。如果不希望这样的结果,用 array_values() 对preg_grep() 返回的结果重新索引。

例子 1. preg_grep() 例子

<?php

// return all array elements

// containing floating point numbers

$fl_array preg_grep ("/^(\d+)?\.\d+$/"$array);

?>

preg_match_all

(PHP 3>= 3.0.9, PHP 4 )

preg_match_all -- 进行全局正则表达式匹配

说明

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>",

    $outPREG_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] 为第二组匹配项的数组,以此类推。

<?php

preg_match_all ("|<[^>]+>(.*)</[^>]+>|U",

    "<b>example: </b><div align=left>this is a test</div>",

    $outPREG_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{3})?  \)?  (?(1)  [\-\s] ) \d{3}-\d{4}/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$icount($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]."\n\n";

}

?>

本例将输出:

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>

preg_match

(PHP 3>= 3.0.9, PHP 4 )

preg_match -- 进行正则表达式匹配

说明

int preg_match ( string pattern, string subject [, array matches [, int flags]])

 

在 subject 字符串中搜索与 pattern 给出的正则表达式相匹配的内容。

如果提供了 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

提示: 如果只想查看一个字符串是否包含在另一个字符串中,不要用 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_quote

(PHP 3>= 3.0.9, PHP 4 )

preg_quote -- 转义正则表达式字符

 

说明

string preg_quote ( string str [, string delimiter])

 

preg