This question already has answers here:
What does the syntax '%s' and '%d' mean as shorthand for calling a variable?
(3 answers)
Closed 11 months ago.
I'm looking at Webmonkey's PHP and MySql Tutorial, Lesson 2. I think it's a php literal. What does %s mean? It's inside the print_f() function in the while loops in at least the first couple of code blocks.
printf("<tr><td>%s %s</td><td>%s</td></tr>n", ...
with printf or sprintf characters preceded by the % sign are placeholders (or tokens). They will be replaced by a variable passed as an argument.
Example:
$str1 = 'best';
$str2 = 'world';
$say = sprintf('Tivie is the %s in the %s!', $str1, $str2);
echo $say;
This will output:
Tivie is the best in the world!
Note: There are more placeholders (%s for string, %d for dec number, etc...)
Order:
The order in which you pass the arguments counts. If you switch $str1 with $str2 as
$say = sprintf('Tivie is the %s in the %s!', $str2, $str1);
it will print
"Tivie is the world in the best!"
You can, however, change the reading order of arguments like this:
$say = sprintf('Tivie is the %2$s in the %1$s!', $str2, $str1);
which will print the sentence correctly.
Also, keep in mind that PHP is a dynamic language and does not require (or support) explicit type definition. That means it juggles variable types as needed. In sprint it means that if you pass a "string" as argument for a number placeholder (%d), that string will be converted to a number (int, float...) which can have strange results. Here's an example:
$onevar = 2;
$anothervar = 'pocket';
$say = sprintf('I have %d chocolate(s) in my %d.', $onevar, $anothervar);
echo $say;
this will print
I have 2 chocolate(s) in my 0.
More reading at PHPdocs
In printf, %s is a placeholder for data that will be inserted into the string. The extra arguments to printf are the values to be inserted. They get associated with the placeholders positionally: the first placeholder gets the first value, the second the second value, and so on.
%s is a type specifier which will be replaced to valuable's value (string) in case of %s.
Besides %s you can use other specifiers, most popular are below:
d - the argument is treated as an integer, and presented as a (signed) decimal number.
f - the argument is treated as a float, and presented as a floating-point number (locale
aware).
s - the argument is treated as and presented as a string.
$num = 5;
$location = 'tree';
$format = 'There are %d monkeys in the %s';
echo sprintf($format, $num, $location);
Will output: "There are 5 monkeys in the tree."
The printf() or sprintf() function writes a formatted string to a variable.
Here is the Syntax:
sprintf(format,arg1,arg2,arg++)
format:
%% - Returns a percent sign
%b - Binary number
%c - The character according to the ASCII value
%d - Signed decimal number (negative, zero or positive)
%e - Scientific notation using a lowercase (e.g. 1.2e+2)
%E - Scientific notation using a uppercase (e.g. 1.2E+2)
%u - Unsigned decimal number (equal to or greater than zero)
%f - Floating-point number (local settings aware)
%F - Floating-point number (not local settings aware)
%g - shorter of %e and %f
%G - shorter of %E and %f
%o - Octal number
%s - String
%x - Hexadecimal number (lowercase letters)
%X - Hexadecimal number (uppercase letters)
arg1:
The argument to be inserted at the first %-sign in the format
string..(Required.)
arg2:
The argument to be inserted at the second %-sign in the format
string. (Optional)
arg++:
The argument to be inserted at the third, fourth, etc. %-sign in
the format string (Optional)
Example 1:
$number = 9;
$str = "New York";
$txt = sprintf("There are approximately %u million people in %s.",$number,$str);
echo $txt;
This will output:
There are approximately 9 million people in New York.
The arg1, arg2, arg++ parameters will be inserted at percent (%) signs in the main string. This function works "step-by-step". At the first % sign, arg1 is inserted, at the second % sign, arg2 is inserted, etc.
Note: If there are more % signs than arguments, you must use
placeholders. A placeholder is inserted after the % sign, and consists
of the argument- number and "\$". Let see another Example:
Example 2
$number = 123;
$txt = sprintf("With 2 decimals: %1\$.2f
<br>With no decimals: %1\$u",$number);
echo $txt;
This will output:
With 2 decimals: 123.00
With no decimals: 123
Another important tip to remember is that:
With printf() and sprintf() functions, escape character is not
backslash '\' but rather '%'. Ie. to print '%' character you need to
escape it with itself:
printf('%%%s%%', 'Nigeria Naira');
This will output:
%Nigeria Naira%
Feel free to explore the official PHP Documentation
Related
How can i go about situation when i have % marks in my string, and I also want to use placeholders. Sprintf() treat all % marks as a placeholders and therefore throws an error that not each placeholder matches with given parameters?
sprintf(
'SELECT formatDateTime(toDateTime(date_time), \'%Y%m%d\') as Ymd, count(tr_cars)
FROM hours_data
WHERE (date_time BETWEEN \'%s\' AND \'%s\') AND station_id = %d
GROUP BY Ymd',
$args['dateFrom'],
$args['dateTo'],
$root['stationId']
)
);
IDE prompt: Conversion specification is not mapped to any parameter.
php output: "debugMessage":
"sprintf(): Too few arguments"
If you need to escape a % symbol, you simply put two of them together %%:
$var = 'Awesome';
sprintf( 'This string is 100%% %s!', $var ); // Output: This string is 100% Awesome!
#Magnus Eriksson is correct though. In this particular instance, you'll want to use Prepared Statements if this is an actual query you're going to run on your database.
This question already has answers here:
PHP and preg_match Regex to pull number with decimal out of string
(4 answers)
Closed 4 years ago.
I am trying to extract digits and decimal point from a string but the decimal point is lost when I am using following regular expression:
<?php
$str = "$40.0000";
echo $str;
echo "<br />";
$pattern = "/\D+/";
$str = preg_replace($pattern, '', $str);
echo $str;
?>
Output:
$40.0000
400000
I want to retain dot also. How to include dot in my regex?
<?php
$str = '$40000.00';
echo preg_replace('/[^\d.]/','',$str);
Several good answers here, too: How do I convert output of number_format back to numbers in PHP?
There are two appropriate functions for this purpose. The first, round(), rounds a value to a specified number of decimal places. The function’s first argument is the number to be rounded. This can be either a number or a variable with a number value. The second argument is optional; it represents the number of decimal places to round to. For example:
round (4.30); // 4
round (4.289, 2); // 4.29
$num = 236.26985;
round ($num); // 236
The other function you can use in this situation is number_format(). It works like round() in that it takes a number (or a variable with a numeric value) and an optional decimal specifier. This function has the added benefit of formatting the number with commas, the way it would commonly be written:
number_format (428.4959, 2); // 428.50
number_format (428, 2); // 428.00
number_format (123456789); // 123,456,789
I have script that identifies with preg_match_all some numbers from a given file and in a given format '#(\d\,\d\d\d\d)#' (decimal, with 4 decimals). With them, later, I need to do some math operations to find out the sum, average etc.
With print_r I can see all matches from the array and it is ok (4,3456, 4,9098, etc.). I verify the type of variables and gettype() returned string
Unfortunately I cannot do math operations with them because when I use the variables in a math expression the result is always rounded regardless of what came afer the comma.
For example:
4,3456 + 4,9098 + 4,3456 = 12, or 12,0000 -- if I use number_format.
I used . instead of , in the numbers, I formatted the results with number_format, but have had no success. It seems I am missing something.
Thanks for help!
The error happens even before the number_format call -- PHP considers . as the decimal separator, not ,. you need to str_replace all your array elements:
$values_array = str_replace(",", ".", $values_array)
PHP uses the . character as decimal separator, so you have to replace the , by a . in your matched numbers before converting them to numbers:
$number = floatval(strtr("1,234", ",", "."));
// 1.234
Example:
<?php
$numbers = array("1,234", "5,67");
$numbers = str_replace(",", ".", $numbers);
echo number_format($numbers[0] + $numbers[1], 4, ',', ' ');
Try it here: http://codepad.org/LeeTiKPF
I need a regular expression which extract type specifier ( like %d,%s) from a string.
<?
$price = 999.88;
$str = "string";
$string = "this is a %f sample %'-20s,<br> this string is mixed with type specifier like (number:%d's)";
//output 1 :echo sprintf($string,$price,$str,500);
//output 2 should be $string replaced by [#]
?>
output 1
this is a 999.880000 sample --------------string,
this string is mixed with type specifier like (number:500's)
i want to replace all these type specifiers with [#].
how do i write an regular expression for that type specifiers.
what i need is
output 2
this is a [#] sample --------------[#],
this string is mixed with type specifier like (number:[#]'s)
Pascal beat me to it, but here is my (equally not very well tested regex).
'/%(?:(?<swap_position>[0-9]+)\$)?(?<sign>-|\+)?(?<padding>\'.|0|[[:space:]])?(?<alignment>-?)(?<width>[0-9]+)?(?:\.(?<precision>[0-9]+))?(?<type>[%bcdeufFosxX])?/m';
I would be concerned that by converting everything to # you lose the information where someone has swapped the order using 2$, 1$ etc.
I wanted to make it so that if you captured a custom padding character prefixed by a quote, that quote wouldn't be captured, but I couldn't work it out.
Just is not very-well tested, but what about something like this :
$format = "this is a %f sample %'-20s,<br>
this string is mixed with type specifier like (number:%d's)";
$result = preg_replace("#(%[+-]?(([ 0]?)|('.)))-?(\d*)(\.\d*)?[%bcdeufFosxX]#", '[#]', $format);
var_dump($result);
And the result you get is :
string 'this is a [#] sample [#],<br>
this string is mixed with type specifier like (number:[#]'s)' (length=92)
Which kinda looks like the string you were asking for.
According to the documentation of sprintf, the format has to be :
% sign
optional sign specifier : + or -
optional padding specifier : ' ' or '0'
An alternate padding character can be specified by prefixing it with a single quote (')
optional alignment specifier : nothing or '-'
optional number, a width specifier
optional precision specifier : period (`.') followed by an optional decimal digit string
type specifier : one character amongst the ones allowed
This what I tried to match with that regex ^^
Hope this helps ! Have fun ^^
I have a form in which people will be entering dollar values.
Possible inputs:
$999,999,999.99
999,999,999.99
999999999
99,999
$99,999
The user can enter a dollar value however they wish. I want to read the inputs as doubles so I can total them.
I tried just typecasting the strings to doubles but that didn't work. Total just equals 50 when it is output:
$string1 = "$50,000";
$string2 = "$50000";
$string3 = "50,000";
$total = (double)$string1 + (double)$string2 + (double)$string3;
echo $total;
A regex won't convert your string into a number. I would suggest that you use a regex to validate the field (confirm that it fits one of your allowed formats), and then just loop over the string, discarding all non-digit and non-period characters. If you don't care about validation, you could skip the first step. The second step will still strip it down to digits and periods only.
By the way, you cannot safely use floats when calculating currency values. You will lose precision, and very possibly end up with totals that do not exactly match the inputs.
Update: Here are two functions you could use to verify your input and to convert it into a decimal-point representation.
function validateCurrency($string)
{
return preg_match('/^\$?(\d{1,3})(,\d{3})*(.\d{2})?$/', $string) ||
preg_match('/^\$?\d+(.\d{2})?$/', $string);
}
function makeCurrency($string)
{
$newstring = "";
$array = str_split($string);
foreach($array as $char)
{
if (($char >= '0' && $char <= '9') || $char == '.')
{
$newstring .= $char;
}
}
return $newstring;
}
The first function will match the bulk of currency formats you can expect "$99", "99,999.00", etc. It will not match ".00" or "99.", nor will it match most European-style numbers (99.999,00). Use this on your original string to verify that it is a valid currency string.
The second function will just strip out everything except digits and decimal points. Note that by itself it may still return invalid strings (e.g. "", "....", and "abc" come out as "", "....", and ""). Use this to eliminate extraneous commas once the string is validated, or possibly use this by itself if you want to skip validation.
You don't ever want to represent monetary values as floats!
For example, take the following (seemingly straight forward) code:
$x = 1.0;
for ($ii=0; $ii < 10; $ii++) {
$x = $x - .1;
}
var_dump($x);
You might assume that it would produce the value zero, but that is not the case. Since $x is a floating point, it actually ends up being a tiny bit more than zero (1.38777878078E-16), which isn't a big deal in itself, but it means that comparing the value with another value isn't guaranteed to be correct. For example $x == 0 would produce false.
http://p2p.wrox.com/topic.asp?TOPIC_ID=3099
goes through it step by step
[edit] typical...the site seems to be down now... :(
not a one liner, but if you strip out the ','s you can do: (this is pseudocode)
m/^\$?(\d+)(?:\.(\d\d))?$/
$value = $1 + $2/100;
That allows $9.99 but not $9. or $9.9 and fails to complain about missplaced thousands separators (bug or feature?)
There is a potential 'locality' issue here because you are assuming that thousands are done with ',' and cents as '.' but in europe it is opposite (e.g. 1.000,99)
I recommend not to use a float for storing currency values. You can get rounding errors if the sum gets large. (Ok, if it gets very large.)
Better use an integer variable with a large enough range, and store the input in cents, not dollars.
I belive that you can accomplish this with printf, which is similar to the c function of the same name. its parameters can be somewhat esoteric though. you can also use php's number_format function
Assuming that you are getting real money values, you could simply strip characters that are not digits or the decimal point:
(pseudocode)
newnumber = replace(oldnumber, /[^0-9.]/, //)
Now you can convert using something like
double(newnumber)
However, this will not take care of strings such as "5.6.3" and other such non-money strings. Which raises the question, "Do you need to handle badly formatted strings?"