1

I have currency input strings like these.

  • $50 ...I only need 50
  • $60.59 ...I only need 60, need to remove $ and .59
  • €360 ...I only need 360
  • €36.99 ...I only need 36, need to remove and .99
  • £900 ...I only need 900
  • £90.99 ...I only need 90

In other words, I need to remove all currency symbols from the start of the string and I only need the integer value -- the decimal values can be cut off.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Mr Shabir
  • 173
  • 3
  • 16
  • a better idea would be to format a numerical value with the currency format, rather than creating a string that says `$50` See [here](http://php.net/manual/en/function.money-format.php) – Takarii Aug 10 '16 at 13:12

6 Answers6

2

This RegEx should do it

(\$|€|£)\d+

This is even better (thanks to Jan)

[$€£]\d+

Use it with PHP's Preg Match

preg_match — Perform a regular expression match

Daniel
  • 10,641
  • 12
  • 47
  • 85
  • A character class is much faster here: `[$€£]`, additionally, it does not need to be escaped. He was actually looking for the amounts not for the currency. – Jan Aug 10 '16 at 13:16
  • Regex is overkill for this problem. See my answer below. `$str = (int)ltrim($str, '$£€');` – StampyCode Aug 10 '16 at 15:01
  • @StampyCode I don't understand what you mean by overkill. Regex was designed with the very purpose of being a lightweight, simple and quick way to define a search pattern. – Daniel Aug 10 '16 at 15:17
  • @Daniel Built-in functions should be used where possible - Regex is a very powerful engine that can be used to solve complex problems in a simple way, using regex isn't beginner friendly, and is slower and more resource intensive than built-in functions. – StampyCode Aug 10 '16 at 15:27
1

I would recommend not using a regular expression, as it's overkill for this scenario.

$str = (int)ltrim($str, '$£€');

this is all you need.


Performance vs Regex

I ran the above test through a script to see what the time difference is between my answer and using a RegEx, and on average the RegEx solution was ~20% slower.

<?php
function funcA($a) {
    echo (int)ltrim($a, '$£€');
};
function funcB($a) {
    echo preg_replace('/^.*?([0-9]+).*$/', '$1', $a);
};
//setup (only run once):
function changeDataA() {}
function changeDataB() {}

$loops = 50000;
$timeA = 0.0;
$timeB = 0.0;
$prefix =  str_split('€$€');

ob_start();
for($i=0; $i<$loops; ++$i) {
    $a = $prefix[rand(0,2)] . rand(1,999) . '.' . rand(10,99);

    $start = microtime(1);
    funcA($a);
    $timeA += microtime(1) - $start;

    $start = microtime(1);
    funcB($a);
    $timeB += microtime(1) - $start;
}
ob_end_clean();

$timeA = round(1000000 * ($timeA / $loops), 3);
$timeB = round(1000000 * ($timeB / $loops), 3);

echo "
TimeA averaged $timeA microseconds
TimeB averaged $timeB microseconds
";

Timings vary depending on system load, so times should be considered only relative to each other, not compared between executions. Also this isn't a perfect script for performance benchmarking, there are outside influences that can affect these results, but this gives a general idea.

TimeA averaged 5.976 microseconds
TimeB averaged 6.831 microseconds
StampyCode
  • 7,218
  • 3
  • 28
  • 44
  • …but, anyway, I'm not sure what overkills more: simple regular expression or an extra int casting (string -> float -> int). I repeat: not sure, but I think there should be no significant difference. On the other hand, your solution is cleanes and more readable, of course. – bitifet Aug 10 '16 at 15:36
  • :) it doesn't convert to float, goes straight from `(string)"123.45"` to `(int)123` with the cast. – StampyCode Aug 10 '16 at 15:38
  • Sure?? I mean in PHP internals. But, of course, direct conversion It's not actually an issue. – bitifet Aug 11 '16 at 05:59
  • Apart of that, there is another thing I forgave to mention yesterday: The queston text says "all currency tag" even providing examples for only three of that. But there exists much more and there could be new ones in the future apart of the posibility of leading spaces or other dirty characters (Ex. "€ 30" -notice the space). Of course, you can fix it by adding space and many other common currency, but users are terrible testers and you can find "E" instead or "€", dots, commas or any other unicode blank (or not blank) character, etc... – bitifet Aug 11 '16 at 06:12
  • ...that's why, even I like your approach from the simplicity and readability point of view, except if you are *REALLY* sure that you will not receive any of those faults, I still prefer the regular expression approach because it is more robust at no noticeable cost. – bitifet Aug 11 '16 at 06:16
0

You could go for:

<?php

$string = <<<DATA
$50 From here i need only 50
$60.59 From here i need only 60, Need to remove $ and .59
€360 From here i need only 360.
€36.99 From here i need only 36 need to remove € and .99.
£900 From here i need only 900.
£90.99 From here i need only 90.
DATA;

# look for one of $,€,£ followed by digits
$regex = '~[$€£]\K\d+~';

preg_match_all($regex, $string, $amounts);
print_r($amounts);
/*
Array
(
    [0] => Array
        (
            [0] => 50
            [1] => 60
            [2] => 360
            [3] => 36
            [4] => 900
            [5] => 90
        )

)
*/

?>

See a demo on ideone.com.

Jan
  • 42,290
  • 8
  • 54
  • 79
0

Use regular expression. Ex:

$toStr = preg_replace('/^.*?([0-9]+).*$/', '$1', $fromStr);

See preg_replace documentation.

bitifet
  • 3,514
  • 15
  • 37
  • your answer will always strip the first character, and the question symbol is not required - you should be using `/^[^0-9]?([0-9]+)/` – StampyCode Aug 10 '16 at 15:36
  • 1
    No. The question symol makes "*" non greedy. So ".*?" "eats" as much non numeric (even decimal separator) character until first numeric digit that matches [0-9] (\d would also match "." so I did'nt used it). – bitifet Aug 10 '16 at 15:42
0

use below way

    $str = '$50 From here i need only 50
    $60.59 From here i need only 60, Need to remove $ and .59
    €360 From here i need only 360.
    €36.99 From here i need only 36 need to remove € and .99.
    £900 From here i need only 900.
    £90.99 From here i need only 90.';

    $arr_ = array('$','€','£');

    echo str_replace($arr_,'',$str);
AmmyTech
  • 738
  • 4
  • 10
0
$newString=$string;
$currencyArray = array("$","€","£"); //just add the new item if you want that to add more
foreach($currencyArray  as $value) 
  $newString= str_replace($value,"",$newString);   

$newString has what you need.

Danyal Sandeelo
  • 12,196
  • 10
  • 47
  • 78