使用正则表达式从逗号分隔列表中删除所有令牌实例

时间:2014-07-30 19:57:47

标签: php regex replace

我有一个逗号分隔的标记列表。我希望使用正则表达式删除特定令牌的所有实例:

$str = "tok1,tok2,tok3";

if($new = preg_replace("/(tok2,|,?tok2)/","",$str)){
    echo $new;
}else{
    echo "Regex failed";
}

这适用于除"tok2,tok2,tok2"之外的所有实例,在这种情况下,替换实际上失败了。为什么替换在上述情况下失败,我该如何解决?

编辑:我是一个完全白痴。我原来的正则表达式一直如预期一样。我本来打算在发生错误时从preg_replace捕获一个null结果,但是没有考虑到emptry字符串也会计算为false。我该如何关闭这个问题?

3 个答案:

答案 0 :(得分:0)

除非你真的只是删除一个具有非常固定格式的字符串,即“tok2”,“ot”,“tok2”,正如Brad所说,str_replace对于这项工作来说已经足够好了。

否则,一个更易于管理的解决方案(个人)将使用array_filter

<?php
$str = "tok1,tok2,tok3,tok2,tok4,tok3";
$tokensToRemove = array('tok2','tok3');
$tokens = explode(',',$str);
$filteredTokens = array_filter($tokens,function($tok) use($tokensToRemove) { return !in_array($tok,$tokensToRemove); });

$newStr = implode(',',$filteredTokens);
var_dump($newStr);

或者如果是旧的PHP版本:

<?php
$str = "tok1,tok2,tok3,tok2,tok4,tok3";
$tokensToRemove = array('tok2','tok3');
$tokens = explode(',',$str);
function removeTokens($tok)
{
    global $tokensToRemove;
    return !in_array($tok,$tokensToRemove);
}
$filteredTokens = array_filter($tokens,'removeTokens');

$newStr = implode(',',$filteredTokens);
var_dump($newStr);

然后,您可以轻松调整$tokensToRemove,并过滤掉所有实例。

答案 1 :(得分:0)

如果字符串操作不是强制性的,我会选择这样的东西:

 <?php
 $str = "tok1,tok2,tok3";
 var_dump(join(",", array_filter(explode(",", $str), function($s) { return $s !== "tok2"; })));
 ?>

三个步骤:

  • 拆分分隔符(,此处)
  • 过滤掉"tok2"
  • 使用分隔符(再次,
  • 连接值

答案 2 :(得分:0)

根据我之前的回答,有一种更简单的方法:

  • 附加一个尾随,
  • 替换每tok2,
  • 删除尾随,

(尾随,只是确保您匹配tok2,,如果它出现在字符串的末尾)

像这样:

$str = "tok1,tok2,tok2,tok3,tok2";

//-----
$str =  $str.","; //append trailing ,
$str = preg_replace("/tok2,/","", $str); //replace every "tok2,"
$str = rtrim($str, ","); //remove trailing , 
//-----

echo $str;

并在一行代码中:

$str = rtrim(preg_replace("/tok2,/","", $str.","), ","); 

不需要魔法: - )

ps。:甚至可以使用

$str = rtrim(str_replace("tok2,","", $str.","), ","); 

可能胜过任何正则表达式。


Yepp,方式更快:

<?php

$start = microtime(true);
for ($i=0; $i<1000000; $i++){
  $str = "tok1,tok2,tok2,tok3";
  $str = rtrim(str_replace("tok2,","", $str.","), ",");
} 
$time_elapsed_us = microtime(true) - $start;
echo "str_replace : " . $time_elapsed_us . "<br />";



$start = microtime(true);
for ($i=0; $i<1000000; $i++){
  $str = "tok1,tok2,tok2,tok3";
  $str = rtrim(preg_replace("/tok2,/","", $str.","), ",");
} 
$time_elapsed_us = microtime(true) - $start;
echo "preg_raplace : " . $time_elapsed_us;
?>

结果(1百万次更换):

str_replace : 1.2485978603363
preg_raplace : 2.1617259979248