PHP 字符串处理:str_replace() 与 preg_replace()
在 PHP 开发中,字符串替换是高频操作。str_replace() 和 preg_replace() 是两个最常用的函数,但它们的适用场景和性能表现差异显著。选错函数可能导致代码效率低下、逻辑错误,甚至安全漏洞。
理解核心区别
str_replace() 执行字面值替换——它把一段固定的文本原样替换成另一段固定文本,不识别任何模式或规则。
preg_replace() 执行正则表达式替换——它根据你定义的“匹配规则”(如“所有数字”、“以 http 开头的链接”)动态查找并替换内容。
简单说:
- 要把
"苹果"全部换成"橙子"→ 用str_replace() - 要把
"价格:123元"中的数字提取出来并加粗 → 用preg_replace()
使用 str_replace():简单、快速、安全
当你知道要替换的确切字符串时,优先使用 str_replace()。它速度快、语法简单、没有安全风险。
调用 str_replace() 的基本格式:
$result = str_replace($search, $replace, $subject);
其中:
$search`:要被替换的字符串(或字符串数组) - `$replace:用来替换的新字符串(或数组)- `$subject`:原始字符串(或数组)
### 常见用法示例
1. **替换单个词**
```php
$text = "我喜欢苹果,苹果很甜。";
$new_text = str_replace("苹果", "香蕉", $text);
// 结果: "我喜欢香蕉,香蕉很甜。"
- 批量替换多个词
$text = "用户名:admin,密码:123456"; $search = ["admin", "123456"]; $replace = ["[已隐藏]", "[已隐藏]"]; $new_text = str_replace($search, $replace, $text); // 结果: "用户名:[已隐藏],密码:[已隐藏]" ``` 3. **统计替换次数(第四个参数)** ```php $count = 0; $result = str_replace("test", "demo", "test test test", $count); // $count 的值为 3 ``` > ⚠️ 注意:`str_replace()` **区分大小写**。若需忽略大小写,请使用 `str_ireplace()`。 --- ## 使用 preg_replace():灵活但需谨慎 当你需要根据**模式**(pattern)进行替换时,比如“所有邮箱地址”、“连续的空白字符”、“URL 链接”,就必须用 `preg_replace()`。 **调用 `preg_replace()` 的基本格式**: ```php $result = preg_replace($pattern, $replacement, $subject); ``` 其中: - `$pattern`:正则表达式,必须用**分隔符包裹**(通常是 `/`)
$replacement`:替换模板,可包含反向引用(如 `$1,$2`) - `$subject:原始字符串
常见用法示例
-
移除所有 HTML 标签
$html = "<p>这是<b>加粗</b>文字。</p>"; $clean = preg_replace("/<[^>]+>/", "", $html); // 结果: "这是加粗文字。" ``` 2. **高亮手机号(中间四位替换成 *)** ```php $text = "联系我:13812345678"; $masked = preg_replace("/(\d{3})\d{4}(\d{4})/", "$1****$2", $text); // 结果: "联系我:138****5678" -
标准化空白字符(多个空格/换行合并为一个空格)
$messy = " 这里 有很多\t\t空格\n\n和换行 "; $clean = preg_replace("/\s+/", " ", trim($messy)); // 结果: "这里 有很多 空格 和换行" ``` > ⚠️ 警告:正则表达式写错可能导致**拒绝服务攻击(ReDoS)**。避免使用嵌套量词(如 `(a+)+`)或模糊匹配。 --- ## 性能与安全性对比 以下表格总结了两者的关键差异: | 特性 | `str_replace()` | `preg_replace()` | | :--- | :---: | :---: | | 匹配方式 | 字面值(精确匹配) | 正则表达式(模式匹配) | | 执行速度 | **极快**(C 层直接操作) | 较慢(需编译和解析正则) | | 大小写敏感 | 是(可用 `str_ireplace()` 忽略) | 取决于正则标志(如 `/i`) | | 安全风险 | 几乎无 | 可能引发 ReDoS 或 XSS(若替换内容来自用户输入) | | 适用场景 | 已知固定字符串替换 | 动态、结构化文本处理 | --- ## 如何选择?三个判断标准 1. **是否知道要替换的**确切内容**? → 是:用 `str_replace()` → 否(只知道“某种格式”):用 `preg_replace()` 2. **是否涉及用户输入?** → 如果 `$search` 或 `$pattern` 来自用户,**绝不能直接拼接到 `preg_replace()`**。必须严格校验或转义。而 `str_replace()` 相对安全。 3. **是否追求极致性能?** → 在循环中处理大量文本时,`str_replace()` 比 `preg_replace()` 快 5~10 倍以上。能不用正则就不用。 --- ## 实战建议:最佳实践 1. **永远不要用 `preg_replace()` 做简单替换** 错误示例: ```php // ❌ 多此一举且低效 $text = preg_replace("/apple/", "orange", $text); ``` 正确做法: ```php // ✅ 简洁高效 $text = str_replace("apple", "orange", $text); ``` 2. **正则表达式务必加限定符** 避免贪婪匹配导致意外结果。例如匹配 `<div>` 内容时,用非贪婪模式: ```php // ✅ 正确:非贪婪匹配 preg_replace('/<div>(.*?)<\/div>/s', '<section>$1</section>', $html); ``` 3. **对用户输入进行转义** 若必须在 `preg_replace()` 中使用变量,先用 `preg_quote()` 转义特殊字符: ```php $keyword = $_GET['q']; $safe_keyword = preg_quote($keyword, '/'); $highlighted = preg_replace("/($safe_keyword)/i", '<mark>$1</mark>', $content); -
优先考虑内置函数替代复杂正则
- 移除首尾空白 → 用
trim() - 转换大小写 → 用
strtolower()/strtoupper() - 解析 URL → 用
parse_url() - 过滤 HTML → 用
strip_tags()或 HTML Purifier 库
- 移除首尾空白 → 用
只有当内置函数无法满足需求时,才动用 preg_replace()。

暂无评论,快来抢沙发吧!