I have a "price" field in a mysql database, which contains the price of a product in arabic or persian numbers.
Example of number: ۱۲۳۴۵۶۷۸۹۰ //1234567890
I cannot figure out how to format this so that it is formatted in a user-friendly way.
By that I mean, grouped by thousands or something similiar.
This would be ideal: ۱ ۲۳۴ ۵۶۷ ۸۹۰
number_format in php is what I would have used on latin numbers.
Is there any function which I don't know about, to make this possible?
If not, ideas of how to create one is appreciated.
Thanks
You could use a regex like this:
([۱۲۳۴۵۶۷۸۹۰])(?=(?:[۱۲۳۴۵۶۷۸۹۰]{3})+$)
Search and replace with \1, on the string ۱۲۳۴۵۶۷۸۹۰ would give you ۱,۲۳۴,۵۶۷,۸۹۰ (using , instead of space since SO trims them off. But using space in the replace instead will work just as well).
I would have to agree with the suggestion in the comments though, store the data using the numeric types available and convert them on input/output.
If you can store numbers in your database instead of strings (or convert to ascii numbers), then standard currency formatting with group-separators can be done with php5-intl functions. You just need ISO locale and currency codes:
$nf = new \NumberFormatter('fa_IR', \NumberFormatter::CURRENCY);
echo $nf->formatCurrency(1234.1234, 'IRR');
۱٬۲۳۴ ﷼
Otherwise, #rvalvik's answer is good.
See http://php.net/manual/en/class.numberformatter.php
More elegantly written than #rvalvik's regex pattern, you can add a comma after a character that is followed by 3, 6, 9, etc. characters.
Code: (Demo)
$str = '۱۲۳۴۵۶۷۸۹۰';
var_export(
preg_replace(
'~.\K(?=(?:.{3})+$)~u',
",",
$str
)
);
Output:
'۱,۲۳۴,۵۶۷,۸۹۰'
Here is similar answer to a related question.
Related
After having checked everywhere in vain I decided to post this problem here. I am Working on an online shop where the client needs to show automatically a "free shipping label" for all items that cost 100€ or more. I did make a function that worked with plain numbers (80€), but when the price is in this format (2.453,90€) it doesn´t.
I would really appreciate your help if you could shed some light on this issue. Thanks in advance
just remove dot and put dot instead of comma for php to recognize this as a number:
$plainNumber = floor(str_replace(",",".",str_replace(".","","2.453,90")));
if($plainNumber >= 100)
{
//do intended stuff
}
You could use regular expressions to transforms formatted numbers in raw numbers.
$number = preg_replace('/\./', '', $number);
$number = preg_replace('/,/', '.', $number);
You could also store raw numbers instead of formatted numbers.
Stringified data types are a not uncommon beginner error. You should always handle numbers as native numbers and only convert to string when printing them.
When you use numbers, good old comparison operators become useful.
I have the following problem. I need to validate and possibly extract currency from a value that I have received. The trouble starts with the fact that the value can be received in any encoding. Additionally to make things worse I can receive a lot of different values that should be considered correct. Let me give an example
$ 123,123,233.00
123,123.99
123.123.123,99
123.123.123 $
All of these are correct.
What I've tried is adding three arrays:
1. Chars (",","."," ")
2. Digits(0-9)
3. Currency Signs($,€...)
Trouble started when the data came in UTF-8 and I can no longer perform search digit by digit on the value I've received as in UTF-8 Currency signs are multibyte.
Question is what to do !?
I've tried the following thing.
Search for a currency sign. Then replace it with nothing. For some unknown reason PHP only replaces the second byte of the multibyte representation of the currency sign and there is a mysterious sign in the string that fails the whole check.
Any ideas are welcomed.
Datelligent idea may actually be a good simple solution: you could replace every non numerical character except the ones useful for puntuaction, with this regex \D*(?!\d{1,2}[\D$]):
$price=preg_replace('\D*(?!\d{1,2}[\D$])', '', $price);
It would transform 1233,234 234.23 into 1233234234.23.
Careful though, stuff like 123,2 34,234 would end up 123,2 34234. It does assume that punctuation followed by three or more digits isn't relevant, doesn't account for potential typos, will delete the currency symbol, etc... but it may be relevant to the scope of your issue.
Try this:
$price=$_POST['price'];
$price=preg_replace('/[^0-9]/', '', $price);
This way PHP will remove all characters and give you a string containing only numbers, which for handling prices is perfect.
If decimals are needed then modify the RegEx to get them:
$price=preg_replace('[0-9]+(\.[0-9][0-9]?)?', '', $price);
I am working with this daily data feed. To my surprise, one the fields didn't look right after it was in MySQL. (I have no control over who provides the feed.)
So I did a mysqldump and discovered the zip code and the city for this record contained a non-printing char. It displayed it in 'vi' as this:
<200e>
I'm working in PHP and I parse this data and put it into the MySQL database. I have used the trim function on this, but that doesn't get rid of it. The problem is, if you do a query on a zipcode in the MySQL database, it doesn't find the record with the non-printing character.
I'd like the clean this up before it's put into the MySQL database.
What can I do in PHP? At first I thought regular expression to only allow a-z,A-Z, and 0-9, but that's not good for addresses. Addresses use periods, commas, hyphens and perhaps other things I'm not thinking of at the moment.
What's the best approach? I don't know what it's called to define it exactly other than printing characters should only be allowed. Is there another PHP function like trim that does this job? Or regular expression? If so, I'd like an example. Thanks!
I have looked into using the PHP function, and saw this posted at PHP.NET:
<?php
$a = "\tcafé\n";
//This will remove the tab and the line break
echo filter_var($a, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
//This will remove the é.
echo filter_var($a, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);
?>
While using FILTER_FLAG_STRIP_HIGH does indeed strip out the <200e> I mentioned seen in 'vi', I'm concerned that it would strip out the letter's accent in a name such as André.
Maybe a regular expression is the solution?
You can use PHP filters: http://www.php.net/manual/en/function.filter-var.php
I would recommend on using the FILTER_SANITIZE_STRING filter, or anything that fits what you need.
I think you could use this little regex replace:
preg_replace( '/[^[:print:]]+/', '', $your_value);
It basically strip out all non-printing characters from $your_value
I tried this:
<?php
$string = "\tabcde éç ÉäÄéöÖüÜß.,!-\n";
$string = preg_replace('/[^a-z0-9\!\.\, \-éâëïüÿçêîôûéäöüß]/iu', '', $string);
print "[$string]";
It gave:
[abcde éç ÉäÄéöÖüÜß.,!-]
Add all the special characters, you need into the regexp.
If you work in English and do not need to support unicode characters, then allow just [\x20-\x7E]
...and remove all others:
$s = preg_replace('/[^\x20-\x7E]+/', '', $s);
I have a large string variable that is assigned from a database column of type "Text" with Collation latin_swedish_ci.
Because it is in ASCII, I need to replace all non UTF-8 characters before I can put variable into my PDF generation script.
As we all know, the standards used by PDF are evil. If I use plain ASCII input it will go insane and cause a rip in space-time.
So in order to prevent anymore damage to our universe, I need help figuring out why this str_replace() function is only replacing one of a character type and ignoring any repeats of this character
Here is my code:
$tc = str_replace (array("\n", "£", "&"), array("<br/>", "£", "&"), $tc);
Input:
Terms & Conditions: Mandatory charge of £10 for cancellations.
VAT E&EO
Output:
Terms & Conditions: Mandatory charge of £10 for cancellations.
VAT E&EO
As you can see in the output on the second line the str_replace() does not change the ampersand character.
I wonder if this is because its over two lines or something like that.
So any idea how to get the function to work as I want it to, otherwise well your going to wake up with many Micro Blackholes vanishing your bowl of cereal tomorrow.
It looks like what you are trying to achieve could be done using these 2 functions:
nl2br(htmlentities($tc));
The benefit being that if your $tc variables gets any more HTML entities in the future, you won't have to fiddle with your str_replace().
I am trying to sort a 4 character string thats being feed in from a user into a different order. an example might be they type "abcd" which I then take and turn it into "bcad".
Here is an example of my attempt which is not working :P
<?php
$mixedDate = $_REQUEST['userDate'];
$formatted_date = firstSubString($mixedDate,2).secondSubString($mixedDate,3).thirdSubString($mixedDate,1).fourthSubString($mixedDate,4);
//... maybe some other stuff here then echo formatted_date
?>
any help would be appreciated.
Copied from comment:
You could pretty simply do this by doing something like:
$formatted_date = $mixedDate[1].$mixedDate[2].$mixedDate[0].$mixedDate[3];
That way, you don't have to bother with calling a substring method many times, since you're just moving individual characters around.
<?php
$mixedDate = $_REQUEST['userDate'];
$formatted_date = $mixedDate{1}.$mixedDate{2}.$mixedDate{0}.$mixedDate{3};
echo $formatted_date;
?>
The curly syntax allows you to get just that one character from your string.
It should be noted that this works correctly on your sample string, abcd and turns it into bcad if $_REQUEST['userDate'] is abcd.
Look into split() in php. It takes a string and a delimiter then splits the string into an array. Either force the user to use a certain format or use a regex on the input string to put the date into a known format, like dd/mm/yyyy or dd-mm-yyyy, then use the hyphen or / as the delimiter.
Once the string is split into an array, you can rearrange it any way you like.
That is very simple.
If
$mixedDate = 21-12-2010
then, try this
echo substr($mixedDate, 3,
2).'-'.substr($mixedDate, 0,
2).'-'.substr($mixedDate, 6);
this will result in
12-21-2010
This is assuming the format is fixed.
Use str_split() to break the string into single characters:
$char_array = str_split($input_string);
If you know exactly what order you want, and you only have four characters, then from here you can actually just do it the way you wanted from your question, and concatenate the array elements back into a single string, like so:
$output_string = $char_array[2].$char_array[3].$char_array[1].$char_array[4];
If your needs are more complex, you can sort and implode the string:
Use sort() to put the characters into order:
sort($char_array);
Or one of the other related sorting functions that PHP provides if you need a different sort order. If you need an sort order which is specific to your requirements, you can use usort(), which allows you to write a function which defines how the sorting works.
Then re-join the characters into a single string using implode():
$output_string = implode($char_array);
Hope that helps.