如果没有前导数字,则将前导零添加到包含十进制值的数字字符串

Add leading zero to numeric strings containing decimal value if no leading number

我的文本文件大约有 200 行

值可以像

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

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

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

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

您没有检查 . 个字符之前的上下文。

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

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

regex demo详情:

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

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

使用 \.(\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[=10=]', $a). PHP_EOL;
}

输出

0.1
1.5
0.10
0.8

看到一个PHP demo

如果您有一组类似于您提供的值的数组,则无需正则表达式即可解决此问题。使用 floatval 很容易,例如 floatval('.8') 将 return 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"

如果你所有的值都是浮点数或整数表达式,那么你可以直截了当地使用“字符串开头后跟文字点”:(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