Search code examples
phpstringintegercurrencytruncate

Trim symbol and decimal value from currency string


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.


Solution

  • 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