preg_replace匹配所有但第一次出现的东西?

时间:2012-08-02 20:24:32

标签: php regex preg-replace

我正在寻找一种方法来替换除了第一次出现的群组或某个角色以外的所有角色。

例如以下随机字符串:

+Z1A124B555ND124AB+A555

1,5,2,4,A,B和+正在重复整个字符串。

124,555是同时重复出现的字符组。

现在,假设我想删除除第一次出现的555,A和B之外的所有内容。

什么样的正则表达式是合适的?我可以想到一个替换所有的例子:

preg_replace('/555|A|B/','',$string);

像^那样的东西,但我想第一次出现......有什么想法吗?

3 个答案:

答案 0 :(得分:1)

你的字符串总是用加号分隔吗? 555,A和B是否总是出现在第一个“组”中(由+分隔)?

如果是这样,您可以拆分,替换然后加入:

$input = '+Z1A124B555+A124AB+A555';
$array = explode('+', $input, 3); // max 3 elements
$array[2] = str_replace(array('555', 'A', 'B'), '', $array[2]);
$output = implode('+', $array);

PS。当我们可以使用简单的str_replace

时,无需使用正则表达式

使用preg_replace_callback功能:

$replaced = array('555' => 0, 'A' => 0, 'B' => 0);
$input = '+Z1A124B555+A124AB+A555';
$output = preg_replace_callback('/555|[AB]/', function($matches) {
  static $replaced = 0;
  if($replaced++ == 0) return $matches[0];
  return '';
}, $input);

答案 1 :(得分:1)

可以修改此解决方案以执行您想要的操作:PHP: preg_replace (x) occurence?

以下是针对您的修改后的解决方案:

<?php
class Parser {

    private $i;

    public function parse($source) {
        $this->i=array();
        return preg_replace_callback('/555|A|B/', array($this, 'on_match'), $source);
    }

    private function on_match($m) {
        $first=$m[0];
        if(!isset($this->i[$first]))
        {
            echo "I'm HERE";
            $this->i[$first]=1;
        }
        else
        {

            $this->i[$first]++;
        }



        // Return what you want the replacement to be.
        if($this->i[$first]>1)
        {
            $result="";
        }
        else
        {
            $result=$m[0];
        }
        return $result;
    }
}

$sample = '+Z1A124B555ND124AB+A555';
$parse = new Parser();
$result = $parse->parse($sample);
echo "Result is: [$result]\n";
?>

祝你好运!上帝保佑!

答案 2 :(得分:0)

适用于每种模式的更通用的功能。

function replaceAllButFirst($pattern, $replacement, $subject) {

  return preg_replace_callback($pattern,

    function($matches) use ($replacement, $subject) {
      static $s;
      $s++;
      return ($s <= 1) ? $matches[0] : $replacement;
    },

    $subject
  );
}