Jump to content

Regular Expression for currency number format replacement

Recommended Posts

Hello Everyone,


In the process of displaying currency numbers format from the text file, I was using below regular expression which accepts a string like '12.345,67' and should be ok to match any arbitrary number of three (or less) consecutive digits separated by dot before decimal comma separator is matched.


Regular Expression : $_num = preg_replace('/^([0-9]{1,3}\.([0-9]{3}\.)*[0-9]{3}|[0-9]+)(?|,(\d\d))$/', '${1}.${3}', $num)


Can anyone tell me what would be the regular expression if I would like to discard the dot character in the above explained case?


For the record the mentioned example returns '12.345.67' since the actual regular expression swallow the dot digits separator too.


Hopefully you may suggest me a regular expression replacement returning: '12345.67'.


With Regards,


Share this post

Link to post
Share on other sites

I am unclear on what the exact input looks like. Can you provide an example? The regular expression you have above looks to be way over-complicated.


As for formatting the value - do not use regular expression. PHP has a couple of built in functions for formatting numbers and currency. Use RegEx to extract the data and use those functions to format the output.


EDIT: After looking at your RegEx closer I *think* that the input ($num) is only the number that you are trying to format. I was first thinking that the 'number' was included in other text in the input. Again, if you confirm what the input looks like we can provide a better solution.

Edited by Psycho

Share this post

Link to post
Share on other sites

Yes Psycho, it's probably the wrong way to cope with a similar problem.


My approach in this case will be to use NumberFormatter::Parse passing a specific locale such as it_IT in my case. Anyway, If and only if I will be in the situation requiring to implement a specific RegEx solution, in order to develop more robust data munging routines, my solution is going to be like the following:

$num = '4.335,67';

$fmt = numfmt_create( 'it_IT', NumberFormatter::DECIMAL );

if (is_numeric(preg_replace('/(?<=[\d])[\.,]/','${1}', $num)))
  echo $fmt->parse($num);
  echo "Wrong input!";

Please note that you either need to have PHP 5.3 > or you need to install it via PECL intl package 1.0.0. PHP 5.3+ has the support built in. Also have look to php.ini file to enable intl itself.



Share this post

Link to post
Share on other sites

Hmm, OK I'm probably more confused now.


If you have a string that contains a numeric value you should either convert the string to a numeric variable using something like floatval() if the string can be converted or parse the string to a value that can be interpreted as a numeric value. THEN, use the PHP functions to determine how the value would be displayed.


RegEx has it's place, but with respect to this problem, I don't think it is a good solution.


If your input is in the European format of 123,456.78 you can use a simple str_replace() to convert it to a string that can be interpreted as a numeric value. Then you can use number_format() to output the numeric calue. In this case, the conversion of the string to a numeric value will put it in the format that you want. But, I would still use the function number_format() to define how the number should display. Don't combine the processes of interpreting the number within a string and the format for the output of the string.



//Input value
$input_str = "234.454,54";
//Convert to a numeric variable
$number_float = floatval(str_replace(array('.',','), array('','.'), $input_str));
//Create number output_add_rewrite_var
$number_output = number_format($number_float, 2, '.', '');
echo "<br>Input string:\n"; var_dump($input_str);
echo "<br>Number float:\n"; var_dump($number_float);
echo "<br>Number output:\n"; var_dump($number_output);

Share this post

Link to post
Share on other sites

Thank again for your detailed answer. I'd would only add that the end user in our case will be presented with the option to choose which European format to use.


For the reason expressed above, I cannot implement too many assumptions about dots coming before comma or similar hard coded logic.


The user is the owner of his own data in my case. He knows how to cope with his own problem after all. (ie. it_IT, en_US, etc.)



Edited by tezuya

Share this post

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.