Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Search for text of prices, perform a function, and replace with output

I want to be able to find text of prices on a given page that matches a regular Expression, perform a function on it, then replace the output.

Example:

<div>The total is $12</div>
  1. RegEx matches the $12 price text
  2. Take 12 and multiply it by 2 which = 24
  3. Replace 12 with 24

Becomes: <div>The total is $24</div>

Here is a JSFiddle with my test code (Please make sure to reference my questions above for what I am after, thanks!)

Here is the regEx I am using

like image 253
jonshariat Avatar asked Mar 03 '14 04:03

jonshariat


2 Answers

First off, your regex is flawed. It can be fixed and simplified to this:

/\$([\d,]+(?:\.\d+)?)/g

It's designed so that the first capture group will be the number itself without the dollar sign. It finds an optional dollar sign, followed by at least one digit, followed by an optional period, followed by more digits if there was a period.

Then, you can use that in the replace function. To make it double the number, you have to pass a function as the second argument which performs that doubling. This looks like this:

pageText.replace(/\$([\d,]+(?:\.\d+)?)/g,
function (string, c1) {
    //If there are commas, get rid of them and record they were there
    var comma = c1.indexOf(',') != -1;
    c1 = c1.replace(/,/g, '');
    //Parse and double
    var value = '' + (parseFloat(c1) * 2);
    //Reinsert commas if they were there before
    if (comma) {
        var split = value.split(".");
        value = split[0].replace(/(\d)(?=(\d{3})+$)/g, "$1,");
        if(split.length > 1)
            value += "."+split[1];
    }
    //Return with dollar sign prepended
    return '$' + value;
});

c1 is the first capture group, which is just the number without the dollar sign. It's parsed as a float and then doubled. If there was a dollar sign in the original string, a dollar sign is placed in front of that number. If there were commas, they have to be removed and re-added after the number is doubled. After all of that, it's all returned.

Here's an example jsfiddle so you can see it in action: http://jsfiddle.net/dB8bK/49/

like image 174
kabb Avatar answered Nov 08 '22 22:11

kabb


This one should do for you:

document.body.innerHTML = pageText.replace(/\$\d+([.,]\d+)?(?=\D\D)/g, function (match) {
    // getting digits only
    digits = match.replace(/\D/g, "");
    num = "" + digits * 2;

    // handle input: $0.009
    if(digits.match(/^0+/)){
        // left padding
        num = Array(digits.length - String(num * 2).length+1).join('0') + num;
    }

    pos_dot = match.indexOf(".");
    if(pos_dot >= 0){
        pos_dot = match.length - pos_dot - 1;
        num = num.substring(0, num.length - pos_dot) + "." + num.substring(num.length - pos_dot, num.length);

    }

    pos_comma = match.indexOf(",");
    if(pos_comma >= 0){
        pos_comma = match.length - pos_comma - 1;
        num = num.substring(0, num.length - pos_comma) + "," + num.substring(num.length - pos_comma, num.length);
    }

    return "$"+num;
});

Sample Input:

<li>$12</li>
<li>$14.99</li>
<li>$2</li>
<li>$dollars</li>
<li>14.99</li>
<li>$12,000</li>
<li>$12,00,0</li>
<li>$0,009</li>

Sample Output:

$24
$29.98
$4
$dollars
14.99
$24,000
$12,00,0
$0,018

Note: if you need you may adjust the regex by changing the (?=\D\D) portion.

like image 41
Sabuj Hassan Avatar answered Nov 09 '22 00:11

Sabuj Hassan