Menu

PHP preg_replace():正则替换与反向引用

preg_replace($pattern, $replacement, $subject) 替换正则表达式的每一处匹配:preg_replace('/\s+/', ' ', $text) 会合并连续的空白。本文讲解 $1 这样的反向引用、preg_replace_callback、删除非字母数字字符、替换次数限制和计数。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

preg_replace($pattern, $replacement, $subject) 在字符串中找出正则表达式的每一处匹配并替换它。preg_replace('/\s+/', ' ', $text) 会把每一段连续的空格、制表符和换行符替换成一个空格。

原字符串不会被修改;preg_replace() 返回一个新字符串。\b 表示单词边界,所以 cats 没有被替换。

反向引用:1、1、{1} 和 \1

在替换字符串中,$1 代表第一个捕获组匹配到的内容,$2 代表第二个,$0 代表整个匹配。用它们可以重新排列匹配到的文本。

替换字符串要用单引号。在双引号中,"\1" 会变成八进制转义(字节 0x01),而 "${1}" 会被当作名为 1 的变量,这个变量没有定义,而且这种字符串语法从 PHP 8.2 起已被弃用。单引号中的 '\1' 和 '$1' 效果相同,但 $1 是更常见的写法。

删除非字母数字的字符

取反的字符类 [^...] 匹配所有没有列出的字符。把它替换成 '' 就删除了这些字符。对于其他语言的文本,配合 u 修饰符使用 Unicode 类 \p{L}(任意字母)和 \p{N}(任意数字),否则 é、ü 以及所有中文、日文字符都会被删掉。

生成 URL slug

连续使用几个正则,就能把标题变成 URL slug。先转成小写,再把每一段连续的非字母数字字符替换成一个连字符,最后去掉两端的连字符:

多个正则、次数限制和计数

$pattern 和 $replacement 都可以是数组:每个正则按顺序被替换成相同下标的替换字符串。第四个参数限制每个正则的替换次数(-1 表示不限制),第五个参数会收到实际替换的次数。

用 preg_replace_callback 计算替换内容

当替换内容取决于匹配结果时,使用 preg_replace_callback()。它对每个匹配调用一次你的函数,传入 $matches 数组,并插入函数返回的内容。用箭头函数可以把简短的回调写在一行里。

当多个正则各自需要自己的函数时,preg_replace_callback_array() 接收一个由 pattern => callback 组成的数组。

来自变量的替换文本

替换字符串中的 $ 和反斜杠都有特殊含义,所以来自用户或数据库的替换文本可能会被弄乱。价格 $10 会被当作对第 10 组的引用,而这个组并不存在,结果就成了空字符串:

如果要查找的文本和替换文本都不是正则,str_replace() 更简单也更快。想在替换之前先测试正则,见 preg_match()。

常见问题

preg_replace 中怎么使用反向引用?

在替换字符串中用 $1、$2(或 \1)引用捕获组:preg_replace('/(\d{4})-(\d{2})-(\d{2})/', '$3/$2/$1', '2026-03-14') 返回 "14/03/2026"。替换字符串要用单引号,如果引用后面紧跟数字,就用 ${1}。

PHP 中怎么删除所有非字母数字的字符?

preg_replace('/[^a-zA-Z0-9]/', '', $s) 只保留 ASCII 字母和数字。要保留各种语言的文字(é、ü、日本語),配合 u 修饰符使用 Unicode 类:preg_replace('/[^\p{L}\p{N}]/u', '', $s)。

preg_replace 和 preg_replace_callback 有什么区别?

preg_replace() 接收一个带 $1 占位符的固定替换字符串。preg_replace_callback() 会对每个匹配调用一个函数,并使用它的返回值,所以你可以计算出替换内容:转成大写、做数学运算,或者在数组中查找。

应该用 str_replace 还是 preg_replace?

替换固定文本时用 str_replace():它更快,也不需要转义。要替换的文本符合某种规律时用 preg_replace(),比如任意连续空格、任意数字或单词边界。

怎么让 preg_replace 只替换第一个匹配?

第四个参数传入限制次数:preg_replace('/\d+/', '#', 'a1 b2 c3', 1) 返回 "a# b2 c3"。第五个参数按引用传递,会收到实际替换的次数。

Coddy 编程语言插图

和 Coddy 一起学编程

开始