文章目录

PHP 字符串处理:str_replace() 与 preg_replace()

发布于 2026-04-02 01:14:10 · 浏览 7 次 · 评论 0 条

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);
    // 结果: "我喜欢香蕉,香蕉很甜。"
  1. 批量替换多个词
    
    $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:原始字符串

常见用法示例

  1. 移除所有 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"
  2. 标准化空白字符(多个空格/换行合并为一个空格)

    $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);
  3. 优先考虑内置函数替代复杂正则

    • 移除首尾空白 → 用 trim()
    • 转换大小写 → 用 strtolower() / strtoupper()
    • 解析 URL → 用 parse_url()
    • 过滤 HTML → 用 strip_tags() 或 HTML Purifier 库

只有当内置函数无法满足需求时,才动用 preg_replace()

评论 (0)

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

扫一扫,手机查看

扫描上方二维码,在手机上查看本文