preg_replace 以及弃用的e

preg_replace

(PHP 4, PHP 5)

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

说明 ¶

mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )

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

参数 ¶

pattern

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

可以使用一些PCRE修饰符, 包括被弃用的'e'(PREG_REPLACE_EVAL),可以为这个函数指定。

replacement

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

replacement中可以包含后向引用\\n 或(php 4.0.4以上可用)$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 的每一个元素上进行, 并且返回值也会是一个数组。

limit

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

count

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

返回值 ¶

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

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

错误/异常 ¶

当传入 "\e" 修饰符的时候,会产生一个 E_DEPRECATED 级别的错误。

更新日志 ¶

版本说明
5.5.0/e 修饰符已经被弃用了。使用 preg_replace_callback() 代替。参见文档中 PREG_REPLACE_EVAL 关于安全风险的更多信息。
5.1.0增加参数count.
4.0.4增加replacement参数中的'$n'用法。
4.0.2增加了参数limit

范例 ¶

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

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

以上例程会输出:

April1,2003

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

<?php
$string = 'The quick brown fox jumped 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 jumped over the lazy dog.

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

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

以上例程会输出:

The slow black bear jumped over the lazy dog.

Example #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

Example #4 剥离空白字符

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

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

Example #5 使用参数count

<?php
$count = 0;

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

以上例程会输出:

xp***to
3

注释 ¶

Note:

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

参见 ¶

 

 

 

preg_replace_callback

(PHP 4 >= 4.0.5, PHP 5)

preg_replace_callback — 执行一个正则表达式搜索并且使用一个回调进行替换

说明 ¶

mixed preg_replace_callback ( mixed $pattern , callable $callback , mixed $subject [, int $limit = -1 [, int &$count ]] )

这个函数的行为除了 可以指定一个 callback 替代 replacement 进行替换 字符串的计算,其他方面等同于preg_replace()

参数 ¶

pattern

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

callback

一个回调函数,在每次需要替换时调用,调用时函数得到的参数是从subject 中匹配到的结果。回调函数返回真正参与替换的字符串。这是该回调函数的签名:

string handler ( array $matches )

你可能经常会需要callback函数而 仅用于preg_replace_callback()一个地方的调用。在这种情况下,你可以 使用匿名函数来定义一个匿名函数作 为preg_replace_callback()调用时的回调。 这样做你可以保留所有 调用信息在同一个位置并且不会因为一个不在任何其他地方使用的回调函数名称而污染函数名称空间。

Example #1 preg_replace_callback() 和 匿名函数

<?php
/* 一个unix样式的命令行过滤器,用于将段落开始部分的大写字母转换为小写。 */
$fp = fopen("php://stdin", "r") or die("can't read stdin");
while (!feof($fp)) {
    $line = fgets($fp);
    $line = preg_replace_callback(
        '|<p>\s*\w|',
        function ($matches) {
            return strtolower($matches[0]);
        },
        $line
    );
    echo $line;
}
fclose($fp);
?>
subject

要搜索替换的目标字符串或字符串数组。

limit

对于每个模式用于每个 subject 字符串的最大可替换次数。 默认是-1(无限制)。

count

如果指定,这个变量将被填充为替换执行的次数。

返回值 ¶

如果subject是一个数组, preg_replace_callback()返回一个数组,其他情况返回字符串。 错误发生时返回 NULL

如果查找到了匹配,返回替换后的目标字符串(或字符串数组), 其他情况subject 将会无变化返回。

更新日志 ¶

版本说明
5.1.0增加了参数count

范例 ¶

Example #2 preg_replace_callback()示例

<?php
// 将文本中的年份增加一年.
$text = "April fools day is 04/01/2002\n";
$text.= "Last christmas was 12/24/2001\n";
// 回调函数
function next_year($matches)
{
  // 通常: $matches[0]是完成的匹配
  // $matches[1]是第一个捕获子组的匹配
  // 以此类推
  return $matches[1].($matches[2]+1);
}
echo preg_replace_callback(
            "|(\d{2}/\d{2}/)(\d{4})|",
            "next_year",
            $text);

?>

以上例程会输出:

April fools day is 04/01/2003
Last christmas was 12/24/2002

Example #3 preg_replace_callback()使用递归构造处理BB码的封装

<?php
$input = "plain [indent] deep [indent] deeper [/indent] deep [/indent] plain";

function parseTagsRecursive($input)
{
     /* 译注: 对此正则表达式分段分析
     * 首尾两个#是正则分隔符
     * \[indent] 匹配一个原文的[indent]
     * ((?:[^[]|\[(?!/?indent])|(?R))+)分析:
     *   (?:[^[]|\[(?!/?indent])分析:
     *  首先它是一个非捕获子组
     *   两个可选路径, 一个是非[字符, 另一个是[字符但后面紧跟着不是/indent或indent.
     *   (?R) 正则表达式递归
     *     \[/indent] 匹配结束的[/indent]
     * /
    $regex = '#\[indent]((?:[^[]|\[(?!/?indent])|(?R))+)\[/indent]#';

    if (is_array($input)) {
        $input = '<div style="margin-left: 10px">'.$input[1].'</div>';
    }

    return preg_replace_callback($regex, 'parseTagsRecursive', $input);
}

$output = parseTagsRecursive($input);

echo $output;
?>

参见 ¶


转载于:https://www.cnblogs.com/clphp/p/5088239.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值