PHP 入门教程
PHP 正则表达式
本教程共 65 篇 · 第 34 篇 · 更新于 2026-07-24 · 约 5 分钟阅读
PHPPHP8正则表达式preg_matchpreg_replace匹配
34. PHP 正则表达式
本节目标:掌握
preg_match、preg_replace的基础用法,了解常用元字符、分组和命名捕获,能写出常见的匹配模式。
正则表达式(Regular Expression)是文本匹配的利器。验证手机号、提取链接、替换敏感词,都离不开它。
34.1 基础函数
preg_match 匹配一次
<?php
$text = "我的邮箱是 test@example.com";
if (preg_match('/\w+@\w+\.\w+/', $text, $matches)) {
echo "匹配到:" . $matches[0]; // test@example.com
}
preg_match_all 匹配所有
<?php
$html = "<a href='http://a.com'>A</a> <a href='https://b.com'>B</a>";
preg_match_all('/href=[\'"](.+?)[\'"]/', $html, $matches);
print_r($matches[1]);
// Array ( [0] => http://a.com [1] => https://b.com )
preg_replace 替换
<?php
$text = "电话:138-1234-5678,备用:139-8765-4321";
// 把手机号中间四位隐藏
$result = preg_replace('/(\d{3})-\d{4}-(\d{4})/', '$1-****-$2', $text);
echo $result; // 电话:138-****-5678,备用:139-****-4321
34.2 常用元字符
| 元字符 | 含义 |
|---|---|
. | 任意单个字符(除换行) |
\d | 数字 [0-9] |
\w | 字母、数字、下划线 [a-zA-Z0-9_] |
\s | 空白字符 |
^ | 字符串开头 |
$ | 字符串结尾 |
* | 前面字符出现 0 次或多次 |
+ | 前面字符出现 1 次或多次 |
? | 前面字符出现 0 次或 1 次 |
{n,m} | 前面字符出现 n 到 m 次 |
Note正则表达式放在
/pattern/的定界符中,PHP 也支持#pattern#、~pattern~等定界符。
34.3 实用匹配示例
验证手机号(中国大陆)
<?php
$phone = "13812345678";
$pattern = '/^1[3-9]\d{9}$/';
if (preg_match($pattern, $phone)) {
echo "手机号格式正确";
}
验证邮箱
<?php
$email = "user.name+tag@example.co.uk";
$pattern = '/^[\w.+-]+@[\w.-]+\.\w+$/';
if (preg_match($pattern, $email)) {
echo "邮箱格式基本正确";
}
Tip完整邮箱正则极其复杂。生产环境建议用
filter_var($email, FILTER_VALIDATE_EMAIL),更可靠。
提取 HTML 标签内容
<?php
$html = "<h1>标题</h1><p>段落内容</p>";
preg_match_all('/<(\w+)>(.+?)<\/\1>/', $html, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
echo "标签:{$match[1]},内容:{$match[2]}\n";
}
// 标签:h1,内容:标题
// 标签:p,内容:段落内容
34.4 分组与捕获
用小括号 () 创建捕获组,用 $1、$2 或 \1、\2 引用:
<?php
$date = "2026-07-24";
// 提取年、月、日
preg_match('/(\d{4})-(\d{2})-(\d{2})/', $date, $m);
echo "年:{$m[1]},月:{$m[2]},日:{$m[3]}";
// 格式转换:2026-07-24 -> 24/07/2026
$newDate = preg_replace('/(\d{4})-(\d{2})-(\d{2})/', '$3/$2/$1', $date);
echo $newDate; // 24/07/2026
非捕获分组
不需要捕获时用 (?:...) 提升性能:
<?php
$pattern = '/(?:https?:\/\/)?(www\.\w+\.\w+)/';
preg_match($pattern, "https://www.example.com", $m);
echo $m[1]; // www.example.com
34.5 命名捕获(PHP 7+ 推荐)
给捕获组起名字,结果更易读:
<?php
$date = "2026-07-24";
preg_match(
'/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/',
$date,
$matches
);
echo $matches["year"]; // 2026
echo $matches["month"]; // 07
echo $matches["day"]; // 24
Tip命名捕获让代码自文档化,维护时不用数
$1、$2到底对应什么。
34.6 修饰符
放在定界符后面,控制匹配行为:
| 修饰符 | 作用 |
|---|---|
i | 忽略大小写 |
m | 多行模式,^ 和 $ 匹配每行开头结尾 |
s | 单行模式,. 匹配换行符 |
u | UTF-8 模式,正确处理中文 |
<?php
// 忽略大小写
preg_match('/php/i', "PHP 是最好的语言"); // 匹配成功
// 正确处理中文(必须加 u 修饰符)
preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', "张三李四"); // 匹配纯中文
34.7 常见错误提醒
- 定界符冲突:正则里有
/时,定界符改用#或~ - 忘记加
u修饰符:匹配中文时结果异常 - 贪婪匹配过多:
.*会匹配尽可能多,改用.*?非贪婪匹配 - 未转义特殊字符:
.、*、?等要用\.、\*转义
来源:参考了 runoob「PHP PCRE」、w3cschool「PHP 正则表达式」等,改写后所得。