Trimming trailing zeros WITHOUT casting to float - php

Let's try again but a bit more explicitly.
I am printing numbers to the screen and want to make them more friendly to users by stripping off trailing zeros after the decimal point. I have tried casting to a float but this solution is not a good fit as I handle numbers like 0.00000001 which come out along the lines of 0.1-e7 sort of thing which is unfriendly to end users.
I need a solution where number like the following...
12.02000000
12.00000000
0.00000001
...can be printed to the screen like...
12.02
12
0.00000001
Using rtim kills numbers like 10000. number_format needs to know the number of decimal places which may be from 0 to 8. Casting to float does not work. I'm sure that there is some regex for this.

Here is the regex solution as you want:
$repl = preg_replace('/(?>\.0+$|(\.\d*[^0])0+$)/', '$1', $numstr);
Testing:
echo preg_replace('/(?>\.0+$|(\.\d*[^0])0+$)/', '$1', '12.02000000') . "\n";
echo preg_replace('/(?>\.0+$|(\.\d*[^0])0+$)/', '$1', '12.00000000') . "\n";
echo preg_replace('/(?>\.0+$|(\.\d*[^0])0+$)/', '$1', '0.0000000100000000') . "\n";
echo preg_replace('/(?>\.0+$|(\.\d*[^0])0+$)/', '$1', '100000000') . "\n";
Output:
12.02
12
0.00000001
100000000

A slightly simpler solution:
preg_replace("/(\.0*[^0]+)0*|\.0*/", '\1', $number)

After a bit of search for internet i found something that could be useful:
function floattostr( $val )
{
preg_match( "#^([\+\-]|)([0-9]*)(\.([0-9]*?)|)(0*)$#", trim($val), $o );
return $o[1].sprintf('%d',$o[2]).($o[3]!='.'?$o[3]:'');
}
This will give you the output you need i guess
I found here

Here is a non-regex way to do it:
if (strpos($number, '.') !== false) {
$number = rtrim($number, '.0');
}
Ternary operator style:
$number = strpos($number, '.') !== false ? rtrim($number, '.0') : $number;

Related

PHP Replace Leading Zeros with Same Number of Spaces

I'd like to replace a string like 0001 with " 1" with 3 spaces.
I've tried str_replace but that doesn't work on 0010.
I've tried some preg_replace but can't get the replacement right to replace the same number
I've written this basic thing and it works, but am looking for something more efficient if possible.
$pin = '0010';
$temp = ltrim($pin, '0');
$spaces = strlen($pin) - strlen($temp);
for ($x=1;$x<=$spaces;$x++) $temp = ' '.$temp;
echo $temp;
Closest I got with preg_replace was this but I'm not sure what to do with replacement:
preg_replace('/0+/', ' ', $pin)
\G for the win!
https://www.regular-expressions.info/continue.html
\G will match the start of the string and continue to match until it can't.
What is the use of '\G' anchor in regex?
Match a zero from the start of the string, then match every following zero one-at-a-time. Replace every matched zero with a space.
Code: (Demo)
$pin = '0010';
var_export(preg_replace('~\G0~', ' ', $pin));
Output:
' 10'
I don't see how to do this any easier with a regular expression, but you could make your other code more concise by using str_repeat:
$pin = '0010';
$temp = ltrim($pin, '0');
$spaces = strlen($pin) - strlen($temp);
$new_pin = str_repeat(' ', $spaces) . $temp;
echo $new_pin;
You said:
but am looking for something more efficient if possible
First, note that a one-liner isn't necessarily efficient(as you tried for preg_replace() and regex is actually a bit slower since it gets compiled first).
Second, you can better adopt for just a 2 pass approach over the string. This also edits the string in-place without extra string variables which is desirable in your case.
Snippet:
<?php
$str = '000010';
$len = strlen($str);
for($i = 0; $i < $len; ++$i){
if($str[$i] == '0'){
$str[$i] = ' ';
}else{
break;
}
}
echo $str;

Adding something to the start of a variable?

I am looking for some code that allows you to add +44 onto the beginning of my $string variable.
So the ending product would be:
$string = 071111111111
+44071111111111
Your $string variable isn't actually a string in this scenario; it's an integer. Make it a string by putting quotes around it:
$string = "071111111111"
Then you can use the . operator to append one string to another, so you could do this:
$string = "+44" . $string
Now $string is +44071111111111. You can read more about how to use the . (string concatenation operator) on the PHP documentation here.
Other people's suggestions of just keeping $string as an integer wouldn't work: "+44" . 071111111111 is actually +447669584457. Due to the 0 at the start of the number, PHP converts it to an octal number rather than a decimal one.
You can combine strings by .
$string = '+44'.$string;
You can use universal code, which works with another parameters too.
<?php
$code = "+44";
$string = "071111111111";
function prepend(& $string, $code) {
$test = substr_replace($string, $code, 0, 0);
echo $test;
}
prepend($string, $code);
?>

Is there an easier way to truncate a string with PHP regex?

I have a string that looks like the following:
Security/Flow_Setup/Steady_State/Verification
I only need the first two levels (e.g. Security/Flow_Setup) Is there an easier way to get this. Currently I explode the string into an array using: '/' as a delimiter and then piece together elements 0 and 1.
This works but I was hoping for a more elegant solution.
Any thoughts?
I don't think you can get too much more elegant/short than this if you only need the first two pieces:
list($var1, $var2) = explode('/', $str);
Regex is totally unnecessary here.
Someone mentioned dirname in the comments, which I thought was a clever and probably appropriate idea, and very short and readable (and gets you the string you need instead of two separate parts like the code above):
$str = 'Security/Flow_Setup/Steady_State/Verification';
echo dirname(dirname($str));
// Output: Security/Flow_Setup
I believe that you do everything ok. You can try it this way if you like:
$str = "Security/Flow_Setup/Steady_State/Verification";
echo substr($str, 0, strpos($str, '/', strpos($str, '/') + 1));
(No arrays involved, should be a little bit faster)
not a typical usage nor a string function, but since your string is effectively a path, maybe this would suffice...
dirname(dirname('Security/Flow_Setup/Steady_State/Verification'));
Here is the shortest and most efficient one-liner I can come up with:
$firstTwoParts = implode('/', array_slice(explode('/', $str, 3), 0, 2));
This could be wrapped into a function that let's you control how many parts you want:
function first_n_parts ($str, $n, $delimiter = '/') {
return ($n = (int) $n) ? implode($delimiter, array_slice(explode($delimiter, $str, $n + 1), 0, $n)) : '';
}
...so you can do:
echo first_n_parts($str, 1); // Security
echo first_n_parts($str, 2); // Security/Flow_Setup
echo first_n_parts($str, 3); // Security/Flow_Setup/Steady_State
this regex should do it
'/^([a-zA-Z]+\/[a-zA-Z]+)?/'

How to remove all leading zeroes in a string

If I have a string
00020300504
00000234892839
000239074
how can I get rid of the leading zeroes so that I will only have this
20300504
234892839
239074
note that the number above was generated randomly.
ltrim:
$str = ltrim($str, '0');
(string)((int)"00000234892839")
you can add "+" in your variable,
example :
$numString = "0000001123000";
echo +$numString;
Similar to another suggestion, except will not obliterate actual zero:
if (ltrim($str, '0') != '') {
$str = ltrim($str, '0');
} else {
$str = '0';
}
Or as was suggested (as of PHP 5.3), shorthand ternary operator can be used:
$str = ltrim($str, '0') ?: '0';
Don't know why people are using so complex methods to achieve such a simple thing! And regex? Wow!
Here you go, the easiest and simplest way (as explained here: https://nabtron.com/kiss-code/ ):
$a = '000000000000001';
$a += 0;
echo $a; // will output 1
Regex was proposed already, but not correctly:
<?php
$number = '00000004523423400023402340240';
$withoutLeadingZeroes = preg_replace('/^0+/', '', $number)
echo $withoutLeadingZeroes;
?>
output is then:
4523423400023402340240
Background on Regex:
the ^ signals beginning of string and the + sign signals more or none of the preceding sign. Therefore, the regex ^0+ matches all zeroes at the beginning of a string.
I don't think preg_replace is the answer..
old thread but just happen to looking for this today. ltrim and (int) casting is the winner.
<?php
$numString = "0000001123000";
$actualInt = "1123000";
$fixed_str1 = preg_replace('/000+/','',$numString);
$fixed_str2 = ltrim($numString, '0');
$fixed_str3 = (int)$numString;
echo $numString . " Original";
echo "<br>";
echo $fixed_str1 . " Fix1";
echo "<br>";
echo $fixed_str2 . " Fix2";
echo "<br>";
echo $fixed_str3 . " Fix3";
echo "<br>";
echo $actualInt . " Actual integer in string";
//output
0000001123000 Origina
1123 Fix1
1123000 Fix2
1123000 Fix3
1123000 Actual integer in tring
A short hack can be to use round() it will remove leading zeros.
echo round('00020300504'); //20300504
Ajay Kumar offers the simplest echo +$numString;
I use these:
echo round($val = "0005");
echo $val = 0005;
//both output 5
echo round($val = 00000648370000075845);
echo round($val = "00000648370000075845");
//output 648370000075845, no need to care about the other zeroes in the number
//like with regex or comparative functions. Works w/wo single/double quotes
Actually any math function will take the number from the "string" and treat it like so. It's much simpler than any regex or comparative functions.
I saw that in php.net, don't remember where.
Im Fixed with this way.
its very simple. only pass a string its remove zero start of string.
function removeZeroString($str='')
{
while(trim(substr($str,0,1)) === '0')
{
$str = ltrim($str,'0');
}
return $str;
}
Assuming you want a run-on of three or more zeros to be removed and your example is one string:
$test_str ="0002030050400000234892839000239074";
$fixed_str = preg_replace('/000+/','',$test_str);
You can make the regex pattern fit what you need if my assumptions are off.
This help?

Help on parsing formatted string

I have strings:
17s 283ms
48s 968ms
The string values are never the same and I want to extract the "second" value from it. In this case, the 17 and the 48.
I'm not very good with regex, so the workaround I did was this:
$str = "17s 283ms";
$split_str = explode(' ', $str);
foreach($split_str as $val){
if(strpos($val, 's') !== false) $sec = intval($val);
}
The problem is, the character 's' exists in both split_str[0] and split_str[1], so my $sec variable keeps obtaining 283, instead of 17.
Again, I'm not very good with regex, and I'm pretty sure regex is the way to go in this case. Please assist. Thanks.
You don't even need to use regex for this.
$seconds = substr($str, 0, strspn($str, '1234567890'));
The above solution will extract all the digits from the beginning of the string. Doesn't matter if the first non-digit character is "s", a space, or anything else.
But why bother?
You can even just cast $str to an int:
$seconds = (int)$str; // equivalent: intval($str)
See it in action.
Regular expressions are definite overkill for such a simple task. Don't use dynamite to drill holes in the wall.
You could do this like so:
preg_match('/(?<seconds>\d+)s\s*(?<milliseconds>\d+)ms/', $var, $matches);
print_r($matches);
If the string will always be formatted in this manner, you could simply use:
<?php
$timeString = '17s 283ms';
$seconds = substr($timeString, 0, strpos($timeString, 's'));
?>
Well, i guess that you can assume seconds always comes before milliseconds. No need for regexp if the format is consistent. This should do it:
$parts = explode(' ', $str);
$seconds = rtrim($parts[0], 's')
echo $seconds; // 17s
This will split the string by space and take the first part 17s. rtrim is then used to remove 's' and you're left with 17.
(\d+s) \d+ms
is the right regexp. Usage would be something like this:
$str = "17s 283ms";
$groups = array();
preg_match("/(\d+)s \d+ms/", $str, $groups);
Then, your number before ms would be $groups[1].

Categories