admin管理员组

文章数量:1202337

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

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

Share Improve this question edited Mar 8, 2014 at 22:33 jonshariat asked Mar 3, 2014 at 4:25 jonshariatjonshariat 1763 silver badges16 bronze badges 6
  • Do you know how to get the 12? – Sumner Evans Commented Mar 3, 2014 at 4:30
  • You should not be parsing these string values as numbers, this is very error prone. Instead put the data in some sort of object and update the html content from this data. Then you will have a clean representation of the data as numbers. \ – BentOnCoding Commented Mar 3, 2014 at 14:11
  • Yeah I wanna parse as Regex as per my explanation above. It seems people got distracted by where I left off in frustration (Just trying to get a simple string) – jonshariat Commented Mar 3, 2014 at 15:50
  • 1 @jonshariat In the above fiddle do you want the only $12 to be replaced or even the $12,000. – Sai Commented Mar 8, 2014 at 22:56
  • 1 If I am not, you want every price in html to be doubled? – Amit Joki Commented Mar 9, 2014 at 13:14
 |  Show 1 more comment

7 Answers 7

Reset to default 9 +250

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/

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.

Try to see if this is what you're looking for mate.

Basically, I just changed your replace function to

document.body.innerHTML = pageText.replace(/12/g, 'IT WORKS!!!!!!!!!!!');

Since doing just

document.body.innerHTML = pageText.replace('12', 'IT WORKS!!!!!!!!!!!');

will only replace the first occurence of '12'.

Demo

You do not need to use regex. take price inside a span and add a class to this span. Since span is inline element it will not hurt html design.

I think it will be better approach than regEx

try like this:

html:

<div>The total is $<span class="price">12</span></div>

<div>The total is $<span class="price">100</span></div>

Jquery:

 $('.price').each(function(i,e){
      $(this).text(parseFloat($(this).text()*2));
  });

fiddle

function dollarChange(match, p0, p1, p2, offset, string) {
    // pN = Nth in-parentheses match

    // Remove commas (reinjected later)
    var hasComma = (p1.indexOf(',') > -1);
    if (hasComma) p1 = p1.replace(',', '');

    // Get decimal precision
    var precision = 0;
    if (p2) {
        p1 = p1 + p2;
        precision = p2.length - 1;
    }

    // Process number
    p1 = Number(p1);
    var value = p0 + (p1 * 2).toFixed(precision);

    // Inject commas if previously found
    if (hasComma) {
        var parts = value.toString().split('.');
        parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
        value = parts.join('.');
    }

    return value;
}

// Execute replacement
document.body.innerHTML =
    document.body.innerHTML.replace(/([$])([\d,]+)(\.[\d]+)?/g,
                                    dollarChange);

JSFiddle Demo

Theoretically, $ could be replaced by any currency symbol that precedes its value and whose value uses . as the decimal separator.

Note that the regex used here will only match numbers preceded by a dollar sign (e.g. 14.25 will not be matched)

First generate your regex.

var reg_exp = /\$[0-9]*\.?[0-9]*/g;  //This is your Custom Requested Regex 

Generate the list of strings that matches your regex.

var matches = document.body.innerHTML.match(reg_exp)

Assuming you want to search for the regex over all of the body of the HTML.

Define the transformation function

var transform = function(match){
    var result;
    /* Logic for genarting the resulting string, populate it in result */
    result = match.replace('$','');
    result = parseFloat(result);
    result = result * 2;
    result = '$' + result;
    return result;
};

Transform each of the matches into their result.

matches.forEach(function(match){
    console.log(match)
    result = transform(match);
    document.body.innerHTML.replace(match, result)
});

Though there have been other answers to accomplish what you wanted, my answer summarizes it to do it the way you wanted to do it

(function(context){
  var pattern=/(\$)(\d([\d\,\.]+)?)/g,
      callback=function(_,dollar,price){
           price=price.replace(/,/g,''); 
           return dollar + parseFloat(price)*2;
      },
      html=context.innerHTML.replace(pattern,callback);
  context.innerHTML=html;
})(document.body);

if you don't care price reformatting ckeck the fiddle

本文标签: