正则表达式实用技巧
正则表达式是强大的文本处理工具。本文介绍 PHP 中常用的正则表达式场景。
基础匹配函数
php
// preg_match - 匹配一次
if (preg_match('/php/i', 'I love PHP')) {
echo '匹配成功';
}
// preg_match_all - 匹配所有
preg_match_all('/\d+/', '订单 123, 456, 789', $matches);
print_r($matches[0]); // ['123', '456', '789']
// preg_replace - 替换
$text = preg_replace('/\s+/', ' ', 'Hello World'); // 'Hello World'
// preg_split - 分割
$parts = preg_split('/[,;]/', 'a,b;c'); // ['a', 'b', 'c']常用验证模式
php
// 手机号验证(中国大陆)
function isMobile($mobile) {
return preg_match('/^1[3-9]\d{9}$/', $mobile);
}
// 邮箱验证
function isEmail($email) {
return preg_match('/^[\w\-.]+@[\w\-.]+\.\w+$/', $email);
}
// 身份证号(18位)
function isIdCard($id) {
return preg_match('/^\d{17}[\dXx]$/', $id);
}
// URL 验证
function isUrl($url) {
return preg_match('/^https?:\/\/.+/', $url);
}
// 中文字符
function hasChinese($str) {
return preg_match('/[\x{4e00}-\x{9fa5}]/u', $str);
}
// 密码强度(8-20位,包含字母和数字)
function isStrongPassword($pwd) {
return preg_match('/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*?&]{8,20}$/', $pwd);
}数据提取
php
$text = '
联系人:张三,电话:13800138000
联系人:李四,电话:13900139000
';
// 提取所有手机号
preg_match_all('/1[3-9]\d{9}/', $text, $phones);
// 提取姓名和电话
preg_match_all('/联系人:(\S+),电话:(\d{11})/', $text, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
echo "姓名: {$match[1]}, 电话: {$match[2]}\n";
}
// 命名捕获组(PHP 7.3+)
preg_match_all('/联系人:(?<name>\S+),电话:(?<phone>\d{11})/', $text, $matches);
foreach ($matches['name'] as $i => $name) {
echo "$name: {$matches['phone'][$i]}\n";
}替换技巧
php
// 手机号脱敏
$mobile = '13800138000';
$masked = preg_replace('/(\d{3})\d{4}(\d{4})/', '$1****$2', $mobile);
// 138****8000
// 格式化金额
$price = 1234567.89;
$formatted = preg_replace('/\B(?=(\d{3})+(?!\d))/', ',', $price);
// 1,234,567.89
// 过滤危险标签(简单示例,生产环境用 HTML Purifier)
$html = '<script>alert("xss")</script><p>正文</p>';
$safe = preg_replace('/<script[^>]*>.*?<\/script>/is', '', $html);
// 替换多个空格为单个
$text = preg_replace('/\s+/', ' ', $text);
// 换行符统一
$text = preg_replace('/\r\n|\r/', "\n", $text);修饰符说明
php
// i - 不区分大小写
preg_match('/php/i', 'PHP'); // 匹配
// u - UTF-8 模式(处理中文必需)
preg_match('/^\x{4e00}+$/u', '中文'); // 匹配
// s - 点号匹配换行
preg_match('/hello.world/s', "hello\nworld"); // 匹配
// m - 多行模式
preg_match_all('/^\d+/m', "1\n2\n3", $m); // 匹配每行开头数字
// 组合使用
preg_match('/中文+/ius', "中文中文\n中文");注意事项
- 优先使用字符串函数:简单的替换用 str_replace 更快
- 转义特殊字符:preg_quote() 转义正则特殊字符
- 避免贪婪匹配:大文本处理使用非贪婪量词
.*? - 性能考虑:复杂正则可能很慢,考虑分步处理
php
// 转义特殊字符
$keyword = 'C++';
$safe = preg_quote($keyword, '/'); // C\+\+
$pattern = "/$safe/i";