【问题标题】:Add leading zero to numeric strings containing decimal value if no leading number如果没有前导数字,则将前导零添加到包含十进制值的数字字符串
【发布时间】:2022-01-20 12:42:40
【问题描述】:

我在文本文件中有大约 200 行

值可以像

$array = ['.1','1.5','0.10','.8'....];

我正在寻找替换 .number 的特定正则表达式模式,例如 '.1' 或 '.8'

 preg_replace('/\.(\d+)/','0${0}',$array[0]);

它正在工作,但对于值 1.5,它的输出是 10.5,这是错误的。

【问题讨论】:

  • 因为1 未被触及并保留在那里,请在此处查看替换regex101.com/r/eIRa25/1
  • 您能否澄清一下,您是否要替换 text$array = ['.1','1.5','0.10','.8'....];,或者您是否拥有一个实际的数组,以及应该处理的值是单个文本.11.5 等?

标签: php regex preg-replace number-formatting leading-zero


【解决方案1】:

如果你所有的值都是浮点数或整数表达式,那么你可以直接使用“字符串开头后跟文字点”:(Demo)

$array = ['.1', '1.5', '0.10', '.8'];
var_export(preg_replace('/^\./', '0.', $array));

如果您需要确保字符串开头的点后跟一个数字,您可以添加一个前瞻:(Demo)

var_export(preg_replace('/^\.(?=\d)/', '0.', $array));

无论哪种方式,您都不需要利用任何捕获组或反向引用。

知道preg_replace() 会愉快地自行迭代您的数组,这可能对您很有用——无需编写额外的循环。


如果您想直接操作 txt 文件,只需添加 m 模式修饰符,以便 ^ 表示每行的开头。 (Demo)

$txt = <<<TEXT
.1
1.5
0.10
.8
TEXT;
echo preg_replace('/^\.(?=\d)/m', '0.', $txt);

输出:

0.1
1.5
0.10
0.8

【讨论】:

    【解决方案2】:

    使用\.(\d+) 将在1.5 中获得部分匹配并匹配.5

    那么替换将是未触及的1 加上0 加上.5 导致10.5

    您可以替换以点开头的值,并匹配一个后续数字^\.\d

    如果它应该是该行中的唯一值,您也可以在字符串末尾附加一个锚点^\.\d+$

    $array = ['.1','1.5','0.10','.8'];
    foreach($array as $a) {
        echo preg_replace('/^\.\d/','0$0', $a). PHP_EOL;
    }
    

    输出

    0.1
    1.5
    0.10
    0.8
    

    查看PHP demo

    【讨论】:

      【解决方案3】:

      如果您有一组与您提供的值相似的值,则无需正则表达式即可解决此问题。使用floatval 很容易,例如floatval('.8') 将返回0.8。一个通用的例子如下:

      $input = ['.1','1.5','0.10','.8'];
      $output = array_map('floatval', $input);
      print_r($output); // => Array ( [0] => 0.1 [1] => 1.5 [2] => 0.1 [3] => 0.8 )
      

      或者如果你需要严格的字符串:

      $input = ['.1','1.5','0.10','.8'];
      $output = array_map(function($item) {
          return strval(floatval($item));
      }, $input);
      print_r($output); // => Array ( [0] => 0.1 [1] => 1.5 [2] => 0.1 [3] => 0.8 )
      

      或支持箭头函数的简短版本 (PHP >= 7.4):

      $input = ['.1','1.5','0.10','.8'];
      $output = array_map(fn($item) => strval(floatval($item)), $input);
      print_r($output); // => Array ( [0] => 0.1 [1] => 1.5 [2] => 0.1 [3] => 0.8 )
      

      如果您需要对文本中的此类值进行规范化,则可以使用preg_replace_callback + floatval

      $input = "Test text: .1 + 1.5 = 1.6 and 000.10 - .8 = .2";
      $output = preg_replace_callback("|\d*\.\d+|", fn($item) => floatval($item[0]), $input);
      print_r($output); // => "Test text: 0.1 + 1.5 = 1.6 and 0.1 - 0.8 = 0.2"
      

      【讨论】:

        【解决方案4】:

        您没有在. char 之前检查上下文。

        您可以检查' 字符是否存在于. + 数字之前:

        preg_replace("/'\K\.\d+/",'0$0',$array[0]);
        

        请参阅regex demo详情

        • ' - 一个 ' 字符
        • \K - 忘记 ' 匹配的字符
        • \. - 一个 . 字符
        • \d+ - 一位或多位数字

        0$0 模式替换为 0 + 整个匹配值。请注意,明确的 ${0} 反向引用形式仅在反向引用后跟一个字面数字时才需要,而不是在它前面时。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-08-05
          • 2018-11-09
          • 1970-01-01
          • 2019-10-20
          • 2019-08-17
          • 2011-02-03
          • 1970-01-01
          相关资源
          最近更新 更多