I have two strings I want to combine and have not exceed a certain width.
$string = sprintf("%4(%s %s)", $s1, $s2);
//s1 s
Notice how the combined %s %s did not exceed a width of 4.
How can I do this with sprintf?
Thanks!
You probably need to add more detail to your question - what do you want to happen if the fields are longer than 3 characters (4 - one space)?
But maybe this is what you want:
sprintf("%.4s", "$s1 $s2");
That will output the combined string "$s1 $s2", pruned to 4 characters. Of course substr would do the same, this might be useful in the context of a longer format string.
To be honest I hadn't realised before that the precision specifier (. followed by number) could be used with %s.
Im not sure how to do so with sprintf but you can use substr() to do so;
$string = substr("$s1 $s2",0,4);
This should return the same result
Related
I have this float value 1290.00 and I would like to trim the zeros on the right in the cleanest way to get 1290, but Why I got 129 if using trim function?
Code:
<?php
$var = '1290.00';
printf ("value: %s -> %s\n", $var, trim($var, '.00'));
The output:
value: 1290.00 -> 129
I have seen different solutions to it by not using trim function, but why is trim not working? I also tried with GoLang and got the same behavior.
Trim removes characters from the end, individually, not as a phrase. It removes all found characters until it can't find any more in the list. So it removes the 0, the 0, the period, then the 0. In this case, I would recommend either round or number_format
number_format($var, 0, '', ''); // 1290
trim doesn't work like that. You only specify the characters you want to trim once, and two periods are used to specify a range. It will then trim all of those characters from the end.
A more efficient method might be intval($var)
Depending on your usage, note that number_format() also rounds the value (see the first example of the documentation). If you need to truncate the number you could use floor():
number_format(1.9, 0, '', ''); // string(1) "2"
floor(1.9); // 1
I need to change the decimal separator in a given string that has numbers in it.
What RegEx code can ONLY select the thousands separator character in the string?
It need to only select, when there is number around it. For example only when 123,456 I need to select and replace ,
I'm converting English numbers into Persian (e.g: Hello 123 becomes Hello ۱۲۳). Now I need to replace the decimal separator with Persian version too. But I don't know how I can select it with regex. e.g. Hello 121,534 most become Hello ۱۲۱/۵۳۴
The character that needs to be replaced is , with /
Use a regular expression with lookarounds.
$new_string = preg_replace('/(?<=\d),(?=\d)/', '/', $string);
DEMO
(?<=\d) means there has to be a digit before the comma, (?=\d) means there has to be a digit after it. But since these are lookarounds, they're not included in the match, so they don't get replaced.
According to your question, the main problem you face is to convert the English number into the Persian.
In PHP there is a library available that can format and parse numbers according to the locale, you can find it in the class NumberFormatter which makes use of the Unicode Common Locale Data Repository (CLDR) to handle - in the end - all languages known to the world.
So converting a number 123,456 from en_UK (or en_US) to fa_IR is shown in this little example:
$string = '123,456';
$float = (new NumberFormatter('en_UK', NumberFormatter::DECIMAL))->parse($string);
var_dump(
(new NumberFormatter('fa_IR', NumberFormatter::DECIMAL))->format($float)
);
Output:
string(14) "۱۲۳٬۴۵۶"
(play with it on 3v4l.org)
Now this shows (somehow) how to convert the number. I'm not so firm with Persian, so please excuse if I used the wrong locale here. There might be options as well to tell which character to use for grouping, but for the moment for the example, it's just to show that conversion of the numbers is taken care of by existing libraries. You don't need to re-invent this, which is even a sort of miss-wording, this isn't anything a single person could do, or at least it would be sort of insane to do this alone.
So after clarifying on how to convert these numbers, question remains on how to do that on the whole text. Well, why not locate all the potential places looking for and then try to parse the match and if successful (and only if successful) convert it to the different locale.
Luckily the NumberFormatter::parse() method returns false if parsing did fail (there is even more error reporting in case you're interested in more details) so this is workable.
For regular expression matching it only needs a pattern which matches a number (largest match wins) and the replacement can be done by callback. In the following example the translation is done verbose so the actual parsing and formatting is more visible:
# some text
$buffer = <<<TEXT
it need to only select , when there is number around it. for example only
when 123,456 i need to select and replace "," I'm converting English
numbers into Persian (e.g: "Hello 123" becomes "Hello ۱۲۳"). now I need to
replace the Decimal separator with Persian version too. but I don't know how
I can select it with regex. e.g: "Hello 121,534" most become
"Hello ۱۲۱/۵۳۴" The character that needs to be replaced is , with /
TEXT;
# prepare formatters
$inFormat = new NumberFormatter('en_UK', NumberFormatter::DECIMAL);
$outFormat = new NumberFormatter('fa_IR', NumberFormatter::DECIMAL);
$bufferWithFarsiNumbers = preg_replace_callback(
'(\b[1-9]\d{0,2}(?:[ ,.]\d{3})*\b)u',
function (array $matches) use ($inFormat, $outFormat) {
[$number] = $matches;
$result = $inFormat->parse($number);
if (false === $result) {
return $number;
}
return sprintf("< %s (%.4f) = %s >", $number, $result, $outFormat->format($result));
},
$buffer
);
echo $bufferWithFarsiNumbers;
Output:
it need to only select , when there is number around it. for example only
when < 123,456 (123456.0000) = ۱۲۳٬۴۵۶ > i need to select and replace "," I'm converting English
numbers into Persian (e.g: "Hello < 123 (123.0000) = ۱۲۳ >" becomes "Hello ۱۲۳"). now I need to
replace the Decimal separator with Persian version too. but I don't know how
I can select it with regex. e.g: "Hello < 121,534 (121534.0000) = ۱۲۱٬۵۳۴ >" most become
"Hello ۱۲۱/۵۳۴" The character that needs to be replaced is , with /
Here the magic is just two bring the string parts into action with the number conversion by making use of preg_replace_callback with a regular expression pattern which should match the needs in your question but is relatively easy to refine as you define the whole number part and false positives are filtered thanks to the NumberFormatter class:
pattern for Unicode UTF-8 strings
|
(\b[1-9]\d{0,2}(?:[ ,.]\d{3})*\b)u
| | |
| grouping character |
| |
word boundary -----------------+
(play with it on regex101.com)
Edit:
To only match the same grouping character over multiple thousand blocks, a named reference can be created and referenced back to it for the repetition:
(\b[1-9]\d{0,2}(?:(?<grouping_char>[ ,.])\d{3}(?:(?&grouping_char)\d{3})*)?\b)u
(now this get's less easy to read, get it deciphered and play with it on regex101.com)
To finalize the answer, only the return clause needs to be condensed to return $outFormat->format($result); and the $outFormat NumberFormatter might need some more configuration but as it is available in the closure, this can be done when it is created.
(play with it on 3v4l.org)
I hope this is helpful and opens up a broader picture to not look for solutions only because hitting a wall (and only there). Regex alone most often is not the answer. I'm pretty sure there are regex-freaks which can give you a one-liner which is pretty stable, but the context of using it will not be very stable. However not saying there is only one answer. Instead bringing together different levels of doings (divide and conquer) allows to rely on a stable number conversion even if yet still unsure on how to regex-pattern an English number.
You can write a regex to capture numbers with thousand separator, and then aggregate the two numeric parts with the separator you want :
$text = "Hello, world, 121,534" ;
$pattern = "/([0-9]{1,3}),([0-9]{3})/" ;
$new_text = preg_replace($pattern, "$1X$2", $text); // replace comma per 'X', keep other groups intact.
echo $new_text ; // Hello, world, 121X534
In PHP you can do that using str_replace
$a="Hello 123,456";
echo str_replace(",", "X", $a);
This will return: Hello 123X456
I'm trying to check if a string has a certain number of occurrence of a character.
Example:
$string = '123~456~789~000';
I want to verify if this string has exactly 3 instances of the character ~.
Is that possible using regular expressions?
Yes
/^[^~]*~[^~]*~[^~]*~[^~]*$/
Explanation:
^ ... $ means the whole string in many regex dialects
[^~]* a string of zero or more non-tilde characters
~ a tilde character
The string can have as many non-tilde characters as necessary, appearing anywhere in the string, but must have exactly three tildes, no more and no less.
As single character is technically a substring, and the task is to count the number of its occurences, I suppose the most efficient approach lies in using a special PHP function - substr_count:
$string = '123~456~789~000';
if (substr_count($string, '~') === 3) {
// string is valid
}
Obviously, this approach won't work if you need to count the number of pattern matches (for example, while you can count the number of '0' in your string with substr_count, you better use preg_match_all to count digits).
Yet for this specific question it should be faster overall, as substr_count is optimized for one specific goal - count substrings - when preg_match_all is more on the universal side. )
I believe this should work for a variable number of characters:
^(?:[^~]*~[^~]*){3}$
The advantage here is that you just replace 3 with however many you want to check.
To make it more efficient, it can be written as
^[^~]*(?:~[^~]*){3}$
This is what you are looking for:
EDIT based on comment below:
<?php
$string = '123~456~789~000';
$total = preg_match_all('/~/', $string);
echo $total; // Shows 3
Ok say I have my phone numbers stored in my table as:
"0008675309"
I obviously wouldn't want to display it just like that, I'd want to format it when I call it as:
(000)867-5309
Would it be better to store it in the database with a delimiter such as / - or . So that I can split it later? Or is it possible to split it by the number of characters?
The performance cost and code to process a phone number in any of those formats is simple, so it's really up to your preference. To answer your question, it is very easy to grab the first three characters, the next three, and the last four using for example, substr function.
Here is a one liner that does what you want:
$phone = preg_replace('^(\d{3})(\d{3})(\d{4})$', '($1)$2-$3', $phone);
As a added bonus it won't change the format if the input format doesn't match (international numbers).
If you are only storing North American phone numbers (10 digits), then as #mellamokb noted, you're ok either way. If you may be storing international numbers, you should capture as much detail as you can early on (if possible) since it might be hard to know how to punctuate the number later on.
use preg_split with PREG_SPLIT_NO_EMPTY
The other answers are perfectly correct. In case you wanted the actual code for it, I think the following should do the trick (the indexes may be off by one oops!):
$phone_number="0008675309"
$phone_number=substr_replace($phone_number, "(", 0, 0);
$phone_number=substr_replace($phone_number, ")", 4, 0);
$phone_number=substr_replace($phone_number, "-", 8, 0);
I just posted this question link text about 5 minutes ago and I forgot to mention that the format was like this
"$2,090.99 "
I need the final value like
"209099"
Striping the final extra space and getting rid of any other punctuation in the money value with php so i can store into a mysql decimal 10,2
You can use a regular expression to replace everything that is not a digit:
$output = preg_replace('/\D/', '', $str);
\D is equivalent to [^\d] that is equivalent to [^0-9].
You might be better off using PHP 5.3's MessageFormatter, Locale and Intl classes if you'll be handling different locales and currency formats. The msgfmt_parse() method might just be what you need.