本文主要介绍函数 preg_match()
的语法、参数、返回值以及使用方法和范例。
格式 | preg_match(pattern, subjevt[, match[, flags [, offset]]]) |
|
---|---|---|
参数 | pattern | 用分隔符包围的正则表达式,可能出现修饰符 |
subject | 需要搜索的目标字符串 | |
matches | 用来接收匹配数据,可省略 | |
flags | 只允许出现标志位 PREG_OFFSET_CAPTURE ,可省略 | |
offset | 从 0 开始,表示匹配尝试的开始位置,可省略,默认为 0 此参数值非负则从前面计算,反之从后面计算 | |
返回 | 如果找到匹配返回 true ,否则返回 false |
简单使用
这是一个最简单的用法:
preg_match($pattern, $subject)
捕获匹配数据
出现 matches
参数用来保存匹配结果,匹配成功后设置 matches
所使用的变量(假定这个变量是 $matches
)的规则是:
$matches[0] 正则表达式匹配的所有文本
$matches[1] 第一组捕获型括号捕获的文本
$matches[2] 第二组捕获型括号捕获的文本
$matches[3] 第三组捕获型括号捕获的文本
...
如果你命名了分组,那么该变量中也会保留对应元素。
我们来看一个例子:
if (preg_match('{ / ([^/]+) $}x', $WholePath, $matches))
$FileName = $matches[1];
上面的例子是从输入的完整路径中分离出文件名。使用 if
进行判断是因为在某些情况下如果发生错误,$matches
的值并不一定会发生变化,所以我们不能认定它不为空就表示匹配成功。
末尾被忽略的 "未参与匹配项"
如果有一组捕获型括号没有参与最终匹配将会在 $matches
中生成空字符串,而 $matches
末尾的空字符串都会被忽略掉。
命名捕获
如果使用命名捕获,虽然正则表达式会变长,但是我们也因此可以直接使用我们的命名,来看例子:
if (preg_match('{^(?P<proto> https? ) ://
(?P<host> [^/:]+ )
(?P<port> \d+ )? }x', $url, $matches)) {
$proto = $matches['proto'];
$host = $matches['host'];
$port = $matches['port'] ? $matches['port'] : ($proto == "http" ? 80 : 443);
print "Protocol: $proto\n";
print "Host: $host\n";
print "Port: $port\n";
}
这样在很大程度上变得更加便捷,但事实上也付出了一定的代价,因为用数字编号的捕获依然会插入到 $matches
中。
此外,要特别说明的是,我并不建议你使用数字来命名分组。
用 flags 获得更多细节
前面曾提到一个参数叫做 flags
,可以帮助我们获得更多匹配细节,如果你设置了此参数,且包含了 PREG_OFFSET_CAPTURE
(目前来说它还不能接受其他内容),那么 $matches
中的每个元素将不再是普通字符串,而是变为一个数组,如果匹配成功,其元素 0
为匹配到的文本,元素 1
的内容为匹配到的文本在目标字符串中的偏移量;如果匹配不成功,则分别为空和 -1
。这里提到的偏移量的计算不受最后一个参数 offset
影响,它从 0
开始,通常按照字节来计数,且不会因为使用修饰符 u
而改变。