# PHP正则表达式:preg_match() 与 preg_replace() 详解
正则表达式是PHP中处理文本的强大工具,而`preg_match()`和`preg_replace()`则是其中最常用的两个函数。本文将深入解析这两个函数的使用方法、常见应用场景以及性能优化技巧。
## 一、preg_match() 函数详解
### 基本语法
```php
int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )
```
### 功能说明
`preg_match()`用于执行一个正则表达式匹配,返回匹配的次数(0或1,因为它在第一次匹配后就会停止搜索)。
### 使用示例
1. **简单匹配**
```php
$subject = "Hello World";
$pattern = '/World/';
if (preg_match($pattern, $subject)) {
echo "匹配成功!";
}
```
2. **获取匹配结果**
```php
$subject = "2023-12-15";
$pattern = '/(\d{4})-(\d{2})-(\d{2})/';
if (preg_match($pattern, $subject, $matches)) {
print_r($matches);
/*
输出:
Array
(
[0] => 2023-12-15
[1] => 2023
[2] => 12
[3] => 15
)
*/
}
```
3. **使用命名捕获组**
```php
$subject = "user:john_doe";
$pattern = '/user:(?<username>\w+)/';
if (preg_match($pattern, $subject, $matches)) {
echo "用户名: " . $matches['username']; // 输出:用户名: john_doe
}
```
### 常用修饰符
- `i` - 不区分大小写匹配
- `m` - 多行模式
- `s` - 使点号(.)匹配包括换行符在内的所有字符
- `u` - 启用UTF-8模式
## 二、preg_replace() 函数详解
### 基本语法
```php
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
```
### 功能说明
`preg_replace()`执行一个正则表达式的搜索和替换。
### 使用示例
1. **简单替换**
```php
$subject = "Hello World";
$pattern = '/World/';
$replacement = 'PHP';
echo preg_replace($pattern, $replacement, $subject); // 输出:Hello PHP
```
2. **使用反向引用**
```php
$subject = "2023-12-15";
$pattern = '/(\d{4})-(\d{2})-(\d{2})/';
$replacement = '$3/$2/$1';
echo preg_replace($pattern, $replacement, $subject); // 输出:15/12/2023
```
3. **数组模式替换**
```php
$subject = "The quick brown fox jumps over the lazy dog.";
$patterns = array('/quick/', '/brown/', '/fox/');
$replacements = array('slow', 'black', 'bear');
echo preg_replace($patterns, $replacements, $subject);
// 输出:The slow black bear jumps over the lazy dog.
```
4. **复杂回调替换**
```php
$subject = "April 15, 2003";
$pattern = '/(\w+) (\d+), (\d+)/i';
$replacement = function($matches) {
return $matches[1] . " " . $matches[2] . ", " . ($matches[3] + 1);
};
echo preg_replace_callback($pattern, $replacement, $subject); // 输出:April 15, 2004
```
## 三、性能优化技巧
1. **预编译正则表达式**
对于需要多次使用的正则表达式,可以使用`preg_quote()`进行转义:
```php
$pattern = preg_quote('$12.99', '/');
```
2. **使用非贪婪匹配**
在量词后加`?`实现非贪婪匹配:
```php
$subject = "<b>first</b> and <b>second</b>";
preg_match_all('/<b>(.*?)<\/b>/', $subject, $matches);
```
3. **避免回溯爆炸**
```php
// 不好的写法:容易导致回溯爆炸
$pattern = '/(a+)+$/';
// 改进写法
$pattern = '/a+$/';
```
4. **使用更简单的替代方案**
对于简单的字符串操作,使用`str_replace()`等函数比正则表达式更快:
```php
// 正则表达式
preg_replace('/\./', '', $string);
// 更快的替代方案
str_replace('.', '', $string);
```
## 四、常见应用场景
### 1. 表单验证
```php
// 验证电子邮件
function isValidEmail($email) {
return preg_match('/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/', $email);
}
// 验证手机号码(中国)
function isValidChineseMobile($mobile) {
return preg_match('/^1[3-9]\d{9}$/', $mobile);
}
```
### 2. HTML处理
```php
// 移除HTML标签
$text = '<p>段落</p><a href="#">链接</a>';
$cleanText = preg_replace('/<[^>]*>/', '', $text);
// 提取所有图片链接
$html = '<img src="image1.jpg"><img src="image2.png">';
preg_match_all('/<img[^>]+src="([^"]+)"[^>]*>/i', $html, $matches);
print_r($matches[1]);
```
### 3. URL处理
```php
// 提取URL中的参数
$url = 'https://example.com/page?name=john&age=25';
preg_match_all('/([^?&=#]+)=([^&#]*)/', parse_url($url, PHP_URL_QUERY), $matches);
$params = array_combine($matches[1], $matches[2]);
print_r($params);
```
## 五、常见问题与陷阱
1. **模式分隔符问题**
```php
// 错误:忘记关闭分隔符
// $pattern = '/[a-z';
// 正确
$pattern = '/[a-z]/';
```
2. **特殊字符转义**
```php
// 错误:未转义正则特殊字符
// $pattern = '/1+1=2/';
// 正确
$pattern = '/1\+1=2/';
```
3. **UTF-8编码问题**
```php
// 对于UTF-8文本,添加u修饰符
$pattern = '/[\x{4e00}-\x{9fa5}]+/u';
```
4. **性能问题**
```php
// 避免在循环中重复编译正则表达式
$pattern = '/\d+/';
foreach ($items as $item) {
preg_match($pattern, $item, $matches);
// ...
}
```
## 结语
`preg_match()`和`preg_replace()`是PHP中处理正则表达式的利器,掌握它们可以大大提高文本处理的效率。在使用时,要注意正则表达式的性能优化和安全问题,避免常见的陷阱。对于复杂的文本处理任务,合理使用正则表达式可以事半功倍。
希望本文能帮助你更好地理解和使用PHP中的正则表达式函数!