本文目录导读:

在PHP中,正则分组提取内容主要使用 preg_match() 或 preg_match_all() 函数,以下是详细的使用方法:
基本分组提取
使用 preg_match() 提取单个匹配
$text = "我的手机号是:138-1234-5678";
$pattern = "/(\d{3})-(\d{4})-(\d{4})/";
if (preg_match($pattern, $text, $matches)) {
print_r($matches);
// 输出:
// Array (
// [0] => 138-1234-5678 // 完整匹配
// [1] => 138 // 第1个分组
// [2] => 1234 // 第2个分组
// [3] => 5678 // 第3个分组
// )
echo "区号:".$matches[1]; // 138
echo "中间:".$matches[2]; // 1234
echo "尾号:".$matches[3]; // 5678
}
使用 preg_match_all() 提取所有匹配
$text = "姓名:张三,年龄:25,城市:北京";
$pattern = "/([^:]+):([^,]+)/";
if (preg_match_all($pattern, $text, $matches)) {
print_r($matches);
// 输出:
// Array (
// [0] => Array ( [0] => 姓名:张三 [1] => 年龄:25 [2] => 城市:北京 )
// [1] => Array ( [0] => 姓名 [1] => 年龄 [2] => 城市 )
// [2] => Array ( [0] => 张三 [1] => 25 [2] => 北京 )
// )
// 提取所有姓名、年龄、城市
foreach ($matches[1] as $key => $label) {
echo "$label: " . $matches[2][$key] . "\n";
}
}
命名分组(推荐)
PHP 5.5.0+ 支持命名分组,使代码更易读:
$text = "2024-01-15";
$pattern = "/(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})/";
if (preg_match($pattern, $text, $matches)) {
// 通过名称访问
echo "年份:".$matches['year']; // 2024
echo "月份:".$matches['month']; // 01
echo "日期:".$matches['day']; // 15
// 也可以通过索引访问
echo $matches[0]; // 2024-01-15
echo $matches[1]; // 2024
echo $matches[2]; // 01
echo $matches[3]; // 15
}
实用示例
提取URL参数
$url = "http://example.com?id=123&name=test&page=1";
$pattern = "/(?:[?&])(?P<key>[^=]+)=(?P<value>[^&]+)/";
preg_match_all($pattern, $url, $matches, PREG_SET_ORDER);
$params = [];
foreach ($matches as $match) {
$params[$match['key']] = $match['value'];
}
print_r($params);
// Array ( [id] => 123 [name] => test [page] => 1 )
提取电子邮件信息
$email = "user@example.com";
$pattern = "/(?P<username>[^@]+)@(?P<domain>[^.]+)\.(?P<tld>\w+)/";
if (preg_match($pattern, $email, $matches)) {
echo "用户名:".$matches['username']; // user
echo "域名:".$matches['domain']; // example
echo "顶级域:".$matches['tld']; // com
}
替换中使用分组引用
$text = "2024-01-15";
// 将日期格式从 YYYY-MM-DD 改为 DD/MM/YYYY
$result = preg_replace(
"/(\d{4})-(\d{2})-(\d{2})/",
"$3/$2/$1", // 引用分组
$text
);
echo $result; // 15/01/2024
使用命名分组的替换
$text = "2024-01-15";
$result = preg_replace_callback(
"/(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})/",
function($matches) {
return "{$matches['day']}-{$matches['month']}-{$matches['year']}";
},
$text
);
echo $result; // 15-01-2024
高级技巧
非捕获分组 (?:...)
$text = "The quick brown fox";
$pattern = "/(?:The|A) (\w+) (\w+) fox/";
if (preg_match($pattern, $text, $matches)) {
print_r($matches);
// 注意:分组[1]仍然是第一个捕获组(quick),因为(?:)不捕获
// Array ( [0] => The quick brown fox [1] => quick [2] => brown )
}
贪婪与懒惰匹配
$text = "<div>内容1</div><div>内容2</div>"; // 贪婪匹配(会匹配尽可能多的内容) $pattern1 = "/<div>(.*)<\/div>/"; preg_match($pattern1, $text, $matches1); echo $matches1[1]; // 内容1</div><div>内容2 // 懒惰匹配(会匹配尽可能少的内容) $pattern2 = "/<div>(.*?)<\/div>/"; preg_match($pattern2, $text, $matches2); echo $matches2[1]; // 内容1
常见错误处理
// 错误:忘记转义特殊字符
$text = "价格是$99.99";
$pattern = "/价格是$(\d+)/"; // $会被解释为行尾
// 正确写法
$pattern = "/价格是\$(\d+)/";
// 错误:未检查匹配结果
if (preg_match($pattern, $text, $matches)) {
// 安全使用 $matches[1]
}
// 使用 PREG_OFFSET_CAPTURE 获取位置信息
preg_match("/(\w+)@(\w+)/", "user@example", $matches, PREG_OFFSET_CAPTURE);
print_r($matches);
// 每个匹配包含值和位置
总结建议
- 优先使用命名分组
(?P<name>...),使代码更易读 - 总是检查 preg_match() 返回值(是否成功匹配)
- 使用非捕获分组 当不需要捕获时
- 注意特殊字符转义,特别是 、、 等
- 对于大量文本,考虑使用 preg_match_all() 配合 PREG_SET_ORDER
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播