Date
May. 20th, 2024
 
2024年 4月 13日

Post: PHP 与 RegEx 浅析 002: preg_match()

PHP 与 RegEx 浅析 002: preg_match()

Published 12:04 Apr 19, 2012.

Created by @ezra. Categorized in #Programming, and tagged as #PHP.

Source format: Markdown

Table of Content

本文主要介绍函数 preg_match() 的语法、参数、返回值以及使用方法和范例。

格式 preg_match(pattern, subjevt[, match[, flags [, offset]]])
参数 pattern用分隔符包围的正则表达式,可能出现修饰符
subject需要搜索的目标字符串
matches用来接收匹配数据,可省略
flags只允许出现标志位 PREG_OFFSET_CAPTURE,可省略
offset0 开始,表示匹配尝试的开始位置,可省略,默认为 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 而改变。

Pinned Message
HOTODOGO
I'm looking for a SOFTWARE PROJECT DIRECTOR / SOFTWARE R&D DIRECTOR position in a fresh and dynamic company. I would like to gain the right experience and extend my skills while working in great teams and big projects.
Feel free to contact me.
For more information, please view online résumé or download PDF
本人正在寻求任职 软件项目经理 / 软件技术经理 岗位的机会, 希望加⼊某个新鲜⽽充满活⼒的公司。
如有意向请随时 与我联系
更多信息请 查阅在线简历下载 PDF