Php preg_替换以匹配除首次发生以外的所有事件?

Php preg_替换以匹配除首次发生以外的所有事件?,php,regex,preg-replace,Php,Regex,Preg Replace,我正在寻找一种方法,以取代所有,但第一次出现的一组或一些字符 例如,以下随机字符串: +Z1A124B555ND124AB+A555 1、5、2、4、A、B和+在整个字符串中重复 124555是也在重复出现的字符组 现在,假设我想删除555,A和B中除第一次出现外的所有内容 什么正则表达式比较合适?我可以想出一个例子来代替所有: preg_replace('/555|A|B/','',$string); 类似的,但我想保留第一个事件。。。有什么想法吗?字符串总是用加号分隔吗?555、A和B是

我正在寻找一种方法,以取代所有,但第一次出现的一组或一些字符

例如,以下随机字符串:

+Z1A124B555ND124AB+A555
1、5、2、4、A、B和+在整个字符串中重复

124555是也在重复出现的字符组

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

什么正则表达式比较合适?我可以想出一个例子来代替所有:

preg_replace('/555|A|B/','',$string);
类似的,但我想保留第一个事件。。。有什么想法吗?

字符串总是用加号分隔吗?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);
当我们可以使用简单的str_替换时,不需要使用正则表达式


使用以下功能:

$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);

可以修改此解决方案以满足您的需要:

以下是一个经过修改的解决方案:

<?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";
?>

一个更通用的函数,适用于所有模式

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
  );
}
函数replaceAllButFirst($pattern,$replacement,$subject){
返回preg_replace_回调($pattern),
函数($matches)使用($replacement,$subject){
静态$s;
$s++;

返回($s您可以在
+
处拆分,在除第一个数组元素之外的所有元素上运行正则表达式,然后将替换的字符串连接到单个字符串。我不太理解您的想法。不,不是这样的……根本没有分隔符,它只是一个随机事件,完全是随机的……我将尝试编辑我的示例以使其成为一个示例。)更清楚一点。酷,将匹配数存储在$replaced中是个好主意,所以我想我会坚持使用它!谢谢。我只是想知道,使用$match是否可以,因为它可能返回数组。我的php还在代码第4行抱怨非法的偏移量类型。我将首先尝试找出它:-)虽然是的,但它看起来确实可行。这样/好吧,我的错。
$match
实际上是一个数组。完整的匹配存储在
$match[0]
中。我会更新我的答案的。是的,谢谢,它现在可以工作了。^或者……等等,它不起作用:D我还在试图找出它的错误。是的,它可以工作:)不过,这和刚才制作成一个类的解决方案完全相同。无论如何,谢谢。