简体   繁体   中英

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

I have about 200 lines in text file

values can be like

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

And I am looking specific regex pattern for replace.number like '.1' or '.8'

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

It's working, but for value 1.5 it's output is 10.5 and that's wrong.

You are not checking the context before . char.

You can check is the ' char is present before the . + digits:

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

See the regex demo . Details :

  • ' - a ' char
  • \K - fiorget the ' matched char
  • \. - a . char
  • \d+ - one or more digits

The 0$0 pattern replaces with 0 + the whole match value. Note the unambiguous ${0} backreference form is only required if the backreference is followed with a literal digit, not when it is preceded with it.

Using \.(\d+) will get a partial match in 1.5 and matches .5

Then the replacement will be the untouched 1 plus 0 plus .5 resulting in 10.5

You can replace the values that start with a dot, and match a single following digit ^\.\d

If it should be the only value on the line, you can append an anchor for the end of the string as well ^\.\d+$

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

Output

0.1
1.5
0.10
0.8

See a PHP demo

If you have an array of values similar to the one you presented, then this can be solved without regular expressions. it's easy enough to use floatval ,for example floatval('.8') will return 0.8 . A general example is below:

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

Or if you need to strictly have strings:

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

Or a short version with support for arrow functions (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 )

If you need to normalize such values inside the text, then you can use 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"

If all of your values are float or integer expressions, then you can use bluntly use "start of string followed by literal dot": ( Demo )

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

If you need to make sure that the dot at the start of the string is followed by a digit, you could add a lookahead: ( Demo )

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

Either way, you don't need to leverage any capture groups or backreferences.

It may be useful for you to know that preg_replace() will happily iterate your array on its own -- no additional loop needs to be written.


If you'd like to directly manipulate your txt file, just add a m pattern modifier so that ^ means the start of each line. ( Demo )

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

Output:

0.1
1.5
0.10
0.8

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM