PHP 中的正则表达式

PHP 中的正则表达式(PCRE,Perl Compatible Regular Expressions)是处理字符串的强大工具,常用于验证格式 (如邮箱、手机号)、提取内容 (如从文本中抓链接)、替换字符 (如敏感词过滤)等。PHP 提供了专门的函数(如 preg_match()preg_replace())来执行正则操作,核心语法和通用正则一致,但有一些 PHP 特有的规则(如定界符、修饰符)。

一、PHP 正则的基础规则

在 PHP 中使用正则,必须遵守两个核心规则:

1. 定界符:包裹正则表达式

PHP 的正则必须用定界符 包裹(不能直接写纯正则),定界符可以是任意非字母数字的字符(常用 /#~)。

  • 示例:用 / 作为定界符 → /正则表达式/
  • 作用:区分正则本身和后续的修饰符(见下文),避免歧义。
2. 修饰符:调整匹配规则

修饰符放在定界符后面,用于改变正则的匹配行为(如是否区分大小写)。常用修饰符:

修饰符 作用 示例
i 不区分大小写匹配 /abc/i 会匹配 ABCaBc
g 全局匹配(默认只匹配一次,用 preg_match_all() 配合) /a/g 会匹配所有 a
m 多行模式(^ 匹配每行开头,$ 匹配每行结尾) /^hello/m 匹配多行文本中每行的 hello 开头
s 单行模式(. 匹配换行符 \n /a.b/s 可匹配 a\nb(默认 . 不匹配 \n

二、PHP 正则核心函数

PHP 提供了多个正则处理函数,最常用的有以下 3 个:

1. preg_match():检查是否匹配(只匹配一次)
  • 语法:preg_match(正则, 目标字符串, 匹配结果数组)
  • 作用:判断目标字符串是否符合正则模式,只返回第一个匹配结果
  • 返回值:匹配成功返回 1,失败返回 0,错误返回 false

示例:验证手机号(中国大陆 11 位)

php 复制代码
$phone = "13800138000";
// 正则:以1开头,第二位3-9,后面9位数字(用/作为定界符)
$pattern = '/^1[3-9]\d{9}$/';

// 执行匹配,结果存到$matches数组
if (preg_match($pattern, $phone, $matches)) {
  echo "手机号格式正确!匹配到:" . $matches[0];  // 输出:手机号格式正确!匹配到:13800138000
} else {
  echo "格式错误";
}
  • $matches[0] 是完整匹配的结果;如果正则有分组(()),$matches[1]$matches[2] 等是分组内容。
2. preg_match_all():全局匹配(获取所有匹配结果)
  • 语法:preg_match_all(正则, 目标字符串, 匹配结果数组)
  • 作用:找到目标字符串中所有符合正则的内容,结果存到二维数组中。
  • 返回值:返回完整匹配次数(可能是0),或者如果发生错误返回FALSE。

示例:提取文本中所有邮箱

php 复制代码
$text = "我的邮箱是a@test.com,你的是b_123@example.cn,还有c+abc@mail.com";
// 正则:匹配邮箱(简化版,用#作为定界符,避免/转义)
$pattern = '#\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*#';

// 全局匹配所有邮箱
preg_match_all($pattern, $text, $matches);

// $matches[0] 是所有匹配的邮箱数组
print_r($matches[0]);
// 输出:
// Array (
//   [0] => a@test.com
//   [1] => b_123@example.cn
//   [2] => c+abc@mail.com
// )
3. preg_replace():替换匹配的内容
  • 语法:preg_replace(正则, 替换内容, 目标字符串)
  • 作用:找到所有符合正则的内容,替换为指定字符串。

示例:过滤敏感词(将"bad"替换为" ")*

php 复制代码
$text = "This is a bad word, bad idea!";
$pattern = '/bad/i';  // i修饰符:不区分大小写(匹配bad、Bad、BAD等)
$replacement = '***';

// 替换所有匹配的内容
$result = preg_replace($pattern, $replacement, $text);
echo $result;  // 输出:This is a ***word,*** idea!

三、核心元字符与 PHP 示例

结合 PHP 函数,再巩固下常用元字符的用法(重点理解 *+?() 等):

1. *:匹配前面的字符 0 次或多次
php 复制代码
$str = "ac, abc, abbc";
$pattern = '/ab*c/';  // b可以出现0次、1次、多次

preg_match_all($pattern, $str, $matches);
print_r($matches[0]);  // 输出:Array ( [0] => ac [1] => abc [2] => abbc )
2. +:匹配前面的字符 1 次或多次
php 复制代码
$str = "ac, abc, abbc";
$pattern = '/ab+c/';  // b至少出现1次

preg_match_all($pattern, $str, $matches);
print_r($matches[0]);  // 输出:Array ( [0] => abc [1] => abbc )(不匹配ac,因为b出现0次)
3. ?:匹配前面的字符 0 次或 1 次
php 复制代码
$str = "color, colour";
$pattern = '/colou?r/';  // u可以出现0次或1次(匹配color或colour)

preg_match_all($pattern, $str, $matches);
print_r($matches[0]);  // 输出:Array ( [0] => color [1] => colour )
4. ():分组与捕获(提取子内容)
php 复制代码
$url = "https://www.example.com/path?query";
// 正则:匹配://,然后用()捕获域名(非/的字符)
$pattern = '/:\/\/([^/]+)/';  // ()是分组,用于提取域名

preg_match($pattern, $url, $matches);
echo $matches[0];  // 输出:://www.example.com(完整匹配)
echo $matches[1];  // 输出:www.example.com(第一个分组的内容,即我们要的域名)

四、实战案例:常见场景处理

1. 验证邮箱格式(严格版)
php 复制代码
function isEmail($email) {
  // 正则:支持字母、数字、下划线、+-., 域名支持多级(如.co.uk)
  $pattern = '/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/';
  return preg_match($pattern, $email) === 1;
}

var_dump(isEmail("test@example.com"));  // bool(true)
var_dump(isEmail("test+abc@mail.co.uk"));  // bool(true)
var_dump(isEmail("test@.com"));  // bool(false)(域名不合法)
2. 从 HTML 中提取所有图片链接(<img src="xxx">
php 复制代码
$html = '<img src="pic1.jpg"><img src="images/pic2.png">';
// 正则:匹配<img src="...",捕获引号中的链接(用~作为定界符,避免/转义)
$pattern = '~<img src="([^"]+)"~';

preg_match_all($pattern, $html, $matches);
print_r($matches[1]);  // 输出:Array ( [0] => pic1.jpg [1] => images/pic2.png )
3. 格式化手机号(中间4位用*代替)
php 复制代码
$phone = "13800138000";
$pattern = '/(\d{3})(\d{4})(\d{4})/';  // 分3组:前3位、中间4位、后4位
$replacement = '$1****$3';  // $1引用第一组,$3引用第三组

echo preg_replace($pattern, $replacement, $phone);  // 输出:138****8000

五、注意事项

  1. 定界符冲突 :如果正则中包含定界符(如 /),需要转义(\/)或换其他定界符(如 #)。
    例:匹配 http:// 时,用 #http://#/http:\/\// 更简洁。
  2. 性能问题 :复杂正则(尤其是带 *+ 的贪婪匹配)在处理长字符串时可能卡顿,尽量优化正则(如用非贪婪 *?)。
  3. 转义字符 :PHP 字符串中的 \ 需转义为 \\,例如匹配 \d 时,正则应写为 /\\d/(因为 PHP 会先解析 \ 为转义)。

总结

PHP 正则的核心是:用定界符包裹正则 + 用专门函数执行操作 。掌握 preg_match()preg_match_all()preg_replace() 三个函数,结合元字符(*+?() 等)和修饰符,就能处理大多数字符串场景。多动手测试(比如修改上面的示例参数),很快就能熟练使用~

相关推荐
一人の梅雨2 小时前
买家秀接口深度开发:从内容解析到情感分析的全链路实现
开发语言·php
PHP武器库4 小时前
PHP 高性能队列探索:从 SQLite 到内存,我们该如何选择?
php
探索宇宙真理.6 小时前
DedeCMS命令执行复现&研究 | CVE-2025-6335
经验分享·php·安全漏洞
毕设源码-郭学长16 小时前
【开题答辩全过程】以 PHP茶叶同城配送网站的设计与实现为例,包含答辩的问题和答案
开发语言·php
taller_200016 小时前
VBA之正则表达式(45)-- 拆分材料和规格
正则表达式·正则·数据清洗·提取数据·材料规格
光明磊16 小时前
正则表达式Regex
正则表达式
AI悦创|编程1v11 天前
01-元字符:如何巧妙记忆正则表达式的基本元件?
正则表达式·ai悦创编程一对一教学·python一对一辅导·python一对一教学
Hello.Reader2 天前
优化 Flink 基于状态的 ETL少 Shuffle、不膨胀、可落地的工程
flink·php·etl
課代表2 天前
Acrobat DC 文本域表单验证中的 js 使用
javascript·正则表达式·表单验证·数据完整性·字段验证·事件对象·自定义验证