preg_replace

(PHP 4, PHP 5, PHP 7, PHP 8)

preg_replace执行一个正则表达式的搜索和替换

说明

preg_replace(
    string|array $pattern,
    string|array $replacement,
    string|array $subject,
    int $limit = -1,
    int &$count = null
): string|array|null

搜索 subject 中匹配 pattern 的部分,以 replacement 进行替换。

匹配一个精确的字符串,而不是一个模式, 可以使用 str_replace()str_ireplace() 代替这个函数。

参数

pattern

要搜索的模式。可以是一个字符串或字符串数组。

可以使用一些 PCRE 修饰符

replacement

用于替换的字符串或字符串数组。如果这个参数是一个字符串,并且 pattern 是一个数组,那么所有的模式都使用这个字符串进行替换。如果 patternreplacement 都是数组,每个 pattern 使用 replacement 中对应的元素进行替换。如果 replacement 中的元素比 pattern 中的少,多出来的 pattern 使用空字符串进行替换。

replacement 中可以包含后向引用 \\n$n,语法上首选后者。 每个这样的引用将被匹配到的第 n 个捕获子组捕获到的文本替换。 n 可以是0-99,\\0$0 代表完整的模式匹配文本。捕获子组的序号计数方式为:代表捕获子组的左括号从左到右, 从1开始数。如果要在 replacement 中使用反斜线,必须使用 4 个("\\\\",译注:因为这首先是 PHP 的字符串,经过转义后,是两个,再经过正则表达式引擎后才被认为是一个原文反斜线)。

当在替换模式下工作并且后向引用后面紧跟着需要是另外一个数字 (比如:在一个匹配模式后紧接着增加一个原文数字),不能使用 \\1 这样的语法来描述后向引用。比如,\\11将会使preg_replace() 不能理解你希望的是一个 \\1 后向引用紧跟一个原文 1,还是一个 \\11 后向引用后面不跟任何东西。 这种情况下解决方案是使用 ${1}1。这创建了一个独立的 $1 后向引用, 一个独立的原文 1

当使用被弃用的 e 修饰符时, 这个函数会转义一些字符 (即:'"\ 和 NULL) 然后进行后向引用替换。当这些完成后请确保后向引用解析完后没有单引号或双引号引起的语法错误 (比如: 'strlen(\'$1\')+strlen("$2")')。确保符合 PHP 的 字符串语法,并且符合 eval 语法。因为在完成替换后,引擎会将结果字符串作为 PHP 代码使用 eval 方式进行评估并将返回值作为最终参与替换的字符串。

subject

要进行搜索和替换的字符串或字符串数组。

如果 subject 是一个数组,搜索和替换回在 subject 的每一个元素上进行, 并且返回值也会是一个数组。

如果 subject 是关联数组,则键会保留在返回值中。

limit

每个模式在每个 subject 上进行替换的最大次数。默认是 -1(无限)。

count

如果指定,将会被填充为完成的替换次数。

返回值

如果 subject 是一个数组,preg_replace() 返回一个数组,其他情况下返回一个字符串。

如果匹配被查找到,替换后的 subject 被返回,其他情况下返回没有改变的 subject。如果发生错误,返回 null

错误/异常

"\e" 会并忽略,并产生 E_WARNING 错误。

如果传递的正则表达式无法正常解析,会发出 E_WARNING

示例

示例 #1 使用后向引用紧跟数值原文

<?php
$string
= 'April 15, 2003';
$pattern = '/(\w+) (\d+), (\d+)/i';
$replacement = '${1}1,$3';
echo
preg_replace($pattern, $replacement, $string);
?>

以上示例会输出:

April1,2003

示例 #2 preg_replace() 中使用基于索引的数组

<?php
$string
= 'The quick brown fox jumps over the lazy dog.';
$patterns = array();
$patterns[0] = '/quick/';
$patterns[1] = '/brown/';
$patterns[2] = '/fox/';
$replacements = array();
$replacements[2] = 'bear';
$replacements[1] = 'black';
$replacements[0] = 'slow';
echo
preg_replace($patterns, $replacements, $string);
?>

以上示例会输出:

The bear black slow jumps over the lazy dog.

对模式和替换内容按 key 进行排序我们可以得到期望的结果。

<?php
ksort
($patterns);
ksort($replacements);
echo
preg_replace($patterns, $replacements, $string);
?>

以上示例会输出:

The slow black bear jumps over the lazy dog.

示例 #3 替换一些值

<?php
$patterns
= array ('/(19|20)(\d{2})-(\d{1,2})-(\d{1,2})/',
'/^\s*{(\w+)}\s*=/');
$replace = array ('\3/\4/\1\2', '$\1 =');
echo
preg_replace($patterns, $replace, '{startDate} = 1999-5-27');
?>

以上示例会输出:

$startDate = 5/27/1999

示例 #4 剥离空白字符

这个例子剥离多余的空白字符

<?php
$str
= 'foo o';
$str = preg_replace('/\s\s+/', ' ', $str);
// 将会改变为'foo o'
echo $str;
?>

示例 #5 使用参数 count

<?php
$count
= 0;

echo
preg_replace(array('/\d/', '/\s/'), '*', 'xp 4 to', -1 , $count);
echo
$count; //3
?>

以上示例会输出:

xp***to
3

注释

注意:

当使用数组形式的patternreplacement时, 将会按照key在数组中出现的顺序进行处理. 这不一定和数组的索引顺序一致. 如果你期望使用索引对等方式用replacementpattern 进行替换, 你可以在调用preg_replace()之前对两个数组各进行一次ksort()排序.

注意:

patternreplacement 都是数组时,匹配规则将按顺序执行。也就是说第二个 pattern/replacement 将作用于第一个 pattern/replacement 生成的字符串,而不是原始字符串。 If you want to simulate replacements operating in parallel, such as swapping two values, replace one pattern by an intermediary placeholder, then in a later pair replace that intermediary placeholder with the desired replacement.

<?php
$p
= array('/a/', '/b/', '/c/');
$r = array('b', 'c', 'd');
print_r(preg_replace($p, $r, 'a'));
// 打印 d
?>

参见