【问题标题】:Replace all certain character except first occurrence in PHP替换除 PHP 中第一次出现的所有特定字符
【发布时间】:2010-01-30 10:52:40
【问题描述】:

示例

  • 输入 = 1.1.0.1
  • 预期输出 = 1.101

【问题讨论】:

    标签: php regex preg-replace


    【解决方案1】:

    您可以相当轻松地使用 substr()str_replace()

    $str = '1.1.0.1';
    $pos = strpos($str,'.');
    if ($pos !== false) {
        $str = substr($str,0,$pos+1) . str_replace('.','',substr($str,$pos+1));
    }
    echo $str;
    

    【讨论】:

      【解决方案2】:
      $s = preg_replace('/((?<=\.)[^.]*)\./', '$1', $s);
      

      匹配零个或多个非点字符后跟一个点,但前提是匹配前面有一个点。这可以防止匹配初始数字。仅用组 #1 中捕获的非点字符(数字)替换匹配项。

      【讨论】:

      • @mickmackusa - 已修复。我可能只是把它扔掉了,因为非正则表达式的答案已经被接受了。
      【解决方案3】:
      $input="1.1.1.1";
      $s = explode(".",$input ) ;
      $t=array_slice($s, 1);
      print implode(".",array($s[0] , implode("",$t)) );
      

      $input="1.1.1.1";
      $s = explode(".",$input ,2) ;
      $s[1]=str_replace(".","",$s[1]);
      print implode(".",array($s[0] ,$s[1] ) );
      

      【讨论】:

      • 这个答案缺少教育解释。没有array_splice()implode() 不需要声明空胶水——它是默认值。
      【解决方案4】:
      1. 匹配并释放第一个出现的文字点
      2. 替换所有后续文字点

      代码:(Demo)

      echo preg_replace('~^[^.]*\.(*SKIP)(*FAIL)|\.~', '', $string);
      // 1.101
      

      或使用“继续”字符 (\G),消耗并忘记第一个文字点,然后替换所有后续文字点。

      代码:(Demo)

      echo preg_replace('~(?:^[^.]*\.|\G(?!^))[^.]*\K\.~', '', $string);
      // 1.101
      

      或者简单地检查一个文字点是否有一个文字点出现在字符串的前面。

      代码:(Demo)

      echo preg_replace('~(?<=\.)[^.]*\K\.~', '', $string);
      // 1.101
      

      【讨论】:

        【解决方案5】:

        我虽然 substr_replace() 可以在这里工作,但遗憾的是没有......这是一个正则表达式方法:

        $str = preg_replace('~(\d+\.)(\d+)\.(\d+)\.(\d+)~', '$1$2$3$4', $str);
        

        【讨论】:

        • 这个答案与 OP 的格式化字符串紧密相关,不能用作通用技术。
        【解决方案6】:

        您也可以使用s 开关尝试下面的正则表达式,

        <?php
        $string = '1.1.0.1';
        $pattern = "/(?s)((?<=\.).*?)(\.)/i";
        $replacement = "$1";
        echo preg_replace($pattern, $replacement, $string);
        ?>
        

        输出:

        1.101
        

        【讨论】:

        • 模式中的哪个字母应该受到不区分大小写的模式修饰符的影响?
        【解决方案7】:

        使用正则表达式匹配可以更清楚地描述所需的结果,并避免调用substrstrpos 时容易出错的方法。在这里,我假设在第一个点之前不需要任何文本,,输入可以以必须保留的点开头。区别在于*+ 的量词是否适合以下模式。

        如果您的输入总是很短,一个简单的方法是替换尾随点,直到没有剩余:

        $count = 0;
        $output = $input;
        do {
            $output = preg_replace('/^(.*\.)(.+)\./', '$1$2', $output, -1, $count);
        } while ($count != 0);
        echo $output;
        

        要使用单个正则表达式匹配,请使用 preg_replace_callback 将函数(在本例中为 str_replace)应用到反向引用变量 $2

        $output = preg_replace_callback(
          '/^([^.]*\.)(.+)$/',
          function ($m) { return $m[1] . str_replace('.', '', $m[2]); },
          $input);
        

        示例结果:

        1.1.0.1 - 1.101
        .1.0.1 - .101
        111 - 111
        1.1 - 1.1
        1. - 1.
        .1 - .1
        .1。 - .1
        .... - .

        您可能想在Try It Online! 试用代码和测试用例

        【讨论】:

          猜你喜欢
          • 2015-07-25
          • 2021-12-20
          • 2022-10-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-19
          相关资源
          最近更新 更多