PHP中str_replace和preg_replace

参考:https://phpmianshi.com/?id=317


里字符串替换的函数,有str_replace()、str_ireplace()、substr_replace()、preg_replace()、strtr()等几个,程序员在写程序的时候,往往会根据自己的习惯以及实际情况选用其中一个或多个。这几个函数虽然都有字符串替换的功能,但它们无论从语法到作用,还是速度和效率上都有所不同,所以并非在任何场合都可以使用它们。

preg_replace函数解释

mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )//搜索subject中匹配pattern的部分, 以replacement进行替换。 
  //参数:pattern
    要搜索的模式。可以使一个字符串或字符串数组。
    可以使用一些PCRE修饰符。
  
replacement
    用于替换的字符串或字符串数组。如果这个参数是一个字符串,并且pattern 是一个数组,那么所有的模式都使用这个字符串进行替换。如果pattern和replacement 都是数组,每个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 的每一个元素上进行, 并且返回值也会是一个数组。
                                
limit
    每个模式在每个subject上进行替换的最大次数。默认是 -1(无限)。
                                
count
    如果指定,将会被填充为完成的替换次数。

preg_replace_callback函数解释

mixed preg_replace_callback ( mixed $pattern , callable $callback , mixed $subject [, int $limit = -1 [, int &$count ]] )//执行一个正则表达式搜索并且使用一个回调进行替换
  pattern
    要搜索的模式,可以使字符串或一个字符串数组。
  
callback
    一个回调函数,在每次需要替换时调用,调用时函数得到的参数是从subject 中匹配到的结果。回调函数返回真正参与替换的字符串。这是该回调函数的签名:
    string handler ( array $matches )你可能经常会需要callback函数而 仅用于preg_replace_callback()一个地方的调用。在这种情况下,你可以 使用匿名函数来定义一个匿名函数作 为preg_replace_callback()调用时的回调。 这样做你可以保留所有 调用信息在同一个位置并且不会因为一个不在任何其他地方使用的回调函数名称而污染函数名称空间。
  
subject
    要搜索替换的目标字符串或字符串数组。
  
limit
    对于每个模式用于每个 subject 字符串的最大可替换次数。 默认是-1(无限制)。
  
count
    如果指定,这个变量将被填充为替换执行的次数。

str_replace()与preg_replace()的区别

在字符串替换的函数里,str_replace()的使用率是最高的,它的用法也比较简单,而preg_replace()的使用率相对来说比较低,因为它需要你懂得写正则表达式,而正则表达式有时候并不容易写。

str_replace()与preg_replace()的用法场合是不同的,str_replace被替换(查找)的内容是固定的、确定的,当然可以使用变量,但是变量也表示固定的、确定的内容,比如可以完成把所有的\n替换为<br>等场合。而preg_replace被替换(查找)的内容是用规则来描述的,比如可以把所有的<和>之间的内容(HTML代码)替换掉。当然preg_replace也可以用来替换固定内容。

str_replace速度要比preg_replace快

两者比较,执行效率方面谁更好呢?这就涉及到速度问题了。有人测试发现,str_replace速度要比preg_replace快一些,但好像没有某些人说的快4倍那么多。10w次的两个词替换结果表明:str_replacece 耗时0.38 sec,preg_replace 耗时0.97sec。

str_replace()与str_ireplace()的区别

str_replace()与str_ireplace()的用法是相同的,它们的区别仅仅是str_replace()对大小写敏感,而str_ireplace()不区分大小写。

str_replace()与strtr() 谁的速度更快?

str_replace()与strtr()这两者的执行效率问题,许多人说法不一,有人说strtr()比str_replace()速度快,但有人经过实例证明了str_replace()比strtr()速度快一些。

某网友测试strtr()在strtr(string,array)用法的时候,它比str_replace更慢些。10w次的两个词替换结果表明:str_replacece()耗时0.38 sec,而strtr() 耗时0.52sec。

php程序里,有很多功能是可以用不同的函数来实现的,除了上述几个之外,可能大家也未曾注意过,那就是php判断字符串长度 isset()速度比strlen()更快。在选择使用什么函数的时候,我们最好知道一下那些函数的执行效率如何,这样才能写出更好的程序来。

使用各函数需要注意的问题

在使用上述函数的时候,有些细节大家可能没怎么注意,导致在使用上有时候达不到预期的结果,这里说说这几个函数的一些需要值得注意的地方。

★str_replace()

1) str_replace()区分大小写,要忽视大小写请使用str_ireplace()
2) 了解替换顺序
由于 str_replace() 的替换时从左到右依次进行的,进行多重替换的时候可能会替换掉之前插入的值。

★strtr()

PHP的strtr() 函数,性能要比str_replace()函数高,可以代替str_replace()来使用。

strtr()有两种形式:

string strtr ( string $str , string $from , string $to )
string strtr ( string $str , array $replace_pairs )

当使用第一种的时候,参数$from,$to 的字符串长度一定要相同,否则多余的(不管是$from多还是$to多) 字符被忽略。

比如 $str = 'a-=b' ;

当$from='-=' ,$to='CD',输出'aCDb', 因为'-='与'CD'的长度相同,没有问题。

当$from='-=' ,$to='CDE',输出'aCDb', $to里的'E'被忽略。

当$from='-=' ,$to='C',输出'aC=b', $from里的'='被忽略。

而使用第二种形式, 则没有这个问题, 多余的字条不会忽略。

所以,如果故意用strtr()函数代替str_replace(), 并且使用了第一种形式,则一定要注意这个特征,这可能是一个陷阱。

★preg_replace()

preg_replace()在使用时需要你具备一定正则表达式书写能力,有的规则不太容易写。这里附上几个实例。

实例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 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.

实例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 使用修饰符'e'

这个例子可以捕获输入文本中所有的html标签

<?php
preg_replace("/(<\/?)(\w+)([^>]*>)/e", "'\\1'.strtoupper('\\2').'\\3'", $html_body);
?>

实例5 剥离空白字符

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

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

实例6 替换html标签中某些特殊的a标签为span ,比如替换 有id的a标签,其他不替换,注意: (.+?)  后面?是非贪婪匹配,不加的话,有可能匹配尽可能多的,替换乱了

<?php
        $pattern = "/(<a id=)(.+?)(<\/a>)/i";
        $replacement = "<span id=$2</span>";
        $content = "<a herf=''>11</a><a id='abc' herf=''>11</a><a herf=''>11</a><a id='bcd' herf=''>11</a>";
        $content = preg_replace($pattern,$replacement,$content);

注意:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值