【问题标题】:PHP replace multiple same occurrences with countsPHP用计数替换多个相同的事件
【发布时间】:2018-09-11 08:22:26
【问题描述】:

我该如何更换这个

Lorem ipsum random_5ac18d179707d dolor random_5ac18d179707d sat amet, consectetur random_5ac18decebd4e adipiscing elit.

有了这个

Lorem ipsum random_1 dolor random_1 sat amet,consectetur random_2 肥胖精英。

它的作用是匹配所有相同的“random_xxxxxxxxxxxxx”,并为该组类似匹配项计数 1。然后,该计数会随着每组额外的类似匹配项而增加。每组可能有一个或多个。

我有以下非常接近但不太正确的内容:

function replace($string) {
    $i = 1;
    return preg_replace_callback('/random_\w+/', function () use (&$i) {
        return 'random_' . $i++;
    }, $string);
}

输出如下

Lorem ipsum random_1 dolor random_2 sat amet,consectetur random_3 肥胖精英。

有什么方法可以调整上面的 sn-p 工作吗?

或者也许有一些方法可以使用 preg_match 获取一组唯一匹配项,然后可以循环并用计数器替换?类似的东西:

$string = 'Lorem ipsum random_5ac18d179707d dolor random_5ac18d179707d sit amet, consectetur random_5ac18decebd4e adipiscing elit.';
preg_match('/random_\w+/', $string, $matches);
print_r($matches);

# to get the following array if possible?
Array
(
    [0] => random_5ac18d179707d
    [1] => random_5ac18decebd4e
)

【问题讨论】:

    标签: php regex


    【解决方案1】:

    您也可以这样做:

    preg_match_all('~random_(\w+)~', $string, $m);
    echo strtr($string, array_combine($s = array_unique($m[1]), range(1, count($s))));
    

    Live demo

    如果您认为\w+ 部分可能出现在不遵循random_ 的地方,您需要稍微修改一下上面的代码:

    preg_match_all('~random_\w+~', $string, $m);
    echo strtr($string, array_combine($s = array_unique($m[0]), preg_filter('~^~', 'random_', range(1, count($s)))));
    

    【讨论】:

      【解决方案2】:

      只是另一种解决方案

      $string = 'Lorem ipsum random_5ac18d179707d dolor random_5ac18d179707d sit amet, consectetur random_5ac18decebd4e adipiscing elit.';
      
      preg_match_all('/random_(\w+)/', $string, $matches);
      
      $replace = array_values(array_unique($matches[1]));
      array_unshift($replace, null);
      
      echo str_replace(array_values($replace), array_keys($replace), $string);
      

      【讨论】:

      • 是的,如果第一种方法没有成功,这是我的第二种方法.. preg_match_all vs preg_match 会让我到达那里.. 很好
      【解决方案3】:
       $strings = explode($input," ");
       $outs = array();
       $last = "";
       for ($strings as $i){
           if(!$outs[$i]){
            $outs[$i] = count($outs)+1;
           }
       }
       for ($outs as $key=>$val){
         $input = str_replace($input,$key,"random".$val);
       }
      

      【讨论】:

      • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
      【解决方案4】:

      您的第一个示例几乎解决了问题。只需使用辅助索引来跟踪您之前看过哪些随机数以及您没有看过哪些随机数。

      function replace($string) {
          $i = 1;
          $index = array();
          return preg_replace_callback('/random_\w+/', function ($matches) use (&$i, &$index) {
              $key = $matches[0];
              if ( isset($index[$key]) ) {
                  $num = $index[$key];
              } else {
                  $num = $i++;
                  $index[$key] = $num;
              }
              return 'random_' . $num;
          }, $string);
      }
      

      由于$matches[0] 包含精确匹配的字符串,我们使用该值来查找索引。如果键存在于索引中,我们使用该数字的现有值。如果没有,我们分配一个新的。

      【讨论】:

        猜你喜欢
        • 2019-03-19
        • 2020-08-31
        • 2017-05-09
        • 1970-01-01
        • 2020-06-21
        • 1970-01-01
        • 1970-01-01
        • 2013-10-13
        • 2020-10-17
        相关资源
        最近更新 更多