I am using a simple regex [^0-9.]
that doesn't match any numbers between 0 to 9 and a period in my given string and matches the rest, and I replace that with empty string and then convert my valid value (integer or double) in string format into an integer or double.
For example:
'123A.478' => '123.478'
'123.48' => '123.48'
'123AX' => '123'
I want to also handle negative valued strings as well i.e. if a string has '-123', I want to retain it. So, I need to convert the strings as follows:
'--123.46' => '-123.46',
'123A-.46' => '123.46',
'-123--.46' => '-123.46',
'A-123-.46' => '-123.46'
I tried using a quantifier but I was unable to build a correct regex with my existing one.
Is there any way I can achieve this using regex?
CodePudding user response:
You can use
preg_replace('~^(-)|- ~', '$1', preg_replace('~[^\d.-] ~', '', $s))
See the PHP demo:
<?php
$strings = ['--123.46', '123A-.46', '-123--.46', 'A-123-.46'];
foreach ($strings as $s) {
echo $s . " => " . preg_replace('~^(-)|- ~', '$1', preg_replace('~[^\d.-] ~', '', $s)) . PHP_EOL;
}
Output:
--123.46 => -123.46
123A-.46 => 123.46
-123--.46 => -123.46
A-123-.46 => -123.46
There are two steps:
- All occurrences of the
[^\d.-]
pattern (any char other than a digit, dot or hyphen) are removed from the input string and then - The
^(-)|-
pattern occurrences (the first char in the string that is a hyphen is placed into Capturing group 1 and all other hyphens are just matched) are replaced with$1
, Group 1 value (so, all hyphens are removed but the first one in the string).
CodePudding user response:
You might use an alternation to remove the parts from the example strings, and in the replacement use an empty string.
^[^\d\s] (?=-)|[^\d\s.] (?!\d)
Explanation
^
Start of string[^\d\s]
Match 1 chars other than a digit or a whitespace char(?=-)
Assert a-
directly to the right|
Or[^\d\s.]
Match 1 chars other than a digit, whitespace char or dot(?!\d)
Assert not a digit directly to the right
See a regex demo and a PHP demo.
Example code
$strings = [
"123A.478",
"123.48",
"123AX",
"--123.46",
"123A-.46",
"-123--.46",
"A-123-.46"
];
$pattern = '/^[^\d\s] (?=-)|[^\d\s.] (?!\d)/';
foreach ($strings as $str) {
echo preg_replace($pattern, "", $str) . PHP_EOL;
}
Output
123.478
123.48
123
-123.46
123.46
-123.46
-123.46