问题 搜索价格文本,执行功能,并替换为输出


我希望能够在给定页面上找到与正则表达式匹配的价格文本,对其执行函数,然后替换输出。

例:

<div>The total is $12</div>
  1. RegEx匹配12美元的价格文本
  2. 取12并乘以2 = 24
  3. 用24替换12

变为: <div>The total is $24</div>

这里有一个 JSFiddle我的测试代码 (请确保在上面提到我的问题,谢谢!)

这里是 regEx我正在使用


12427
2018-03-03 04:25


起源

你知道如何获得12吗? - Sumner Evans
您不应该将这些字符串值解析为数字,这非常容易出错。而是将数据放在某种对象中,并从这些数据中更新html内容。然后,您将数据清晰地表示为数字。 \ - BentOnCoding
是的,我想按照上面的解释解析为正则表达式。看起来人们因为我沮丧地离开的地方而分心(只是试图得到一个简单的字符串) - jonshariat
@jonshariat在上面的小提琴中,你想要只需12美元即可更换,甚至是12,000美元。 - Sai
如果我不是,你希望html中的每个价格都加倍? - Amit Joki


答案:


首先,你的正则表达式是有缺陷的。它可以修复和简化为:

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

它的设计使得第一个捕获组将是没有美元符号的数字。它找到一个可选的美元符号,后跟至少一个数字,后跟一个可选的句点,如果有一个句点,则后跟更多的数字。

然后,您可以在替换功能中使用它。为了使数字加倍,你必须传递一个函数作为执行加倍的第二个参数。这看起来像这样:

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是第一个捕获组,它只是没有美元符号的数字。它被解析为浮点然后加倍。如果原始字符串中有美元符号,则会在该数字前面放置一个美元符号。如果有逗号,则必须删除它们并在数字加倍后重新添加。毕竟,这一切都归还了。

这是一个jsfiddle示例,因此您可以看到它的实际效果: http://jsfiddle.net/dB8bK/49/


8
2018-03-08 23:03



谢谢你这就是我想要的。唯一的想法是,它不能处理像12,000,000.99这样的大数字,但我可以解决这个问题。谢谢! - jonshariat
嘿有一些我不明白的事情。 1.我的<H1>成为代码中的<H2> 2.为什么要使用ParseFloat?为什么不把它作为注册号? - jonshariat
12,000,000.99不起作用的原因是因为在您的示例中,您希望使用逗号作为小数的数字仍然加倍。所以正则表达式认为12,000,000.99是一个带有多个小数的数字。 - kabb
@jonshariat我编辑它以便逗号现在可以工作。此外,要修复标题,您必须使其成为必需的美元符号,或者正则表达式将匹配标记中的数字。我也补充说,虽然你可以通过在正则表达式中使美元符号可选来删除它。 - kabb


试着看看这是否是你正在寻找的伴侣。

基本上,我只是改变了你的 replace 功能

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

自从干得好

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

只会取代第一次出现'12'。

演示


2
2018-03-03 04:34



为了解释这一点,附上 g 关于正则表达式是一个 global flag,表示它应该在第一次匹配后继续匹配。 - Vasili Syrakis
嘿@kuna感谢您的回复。我很抱歉我不太清楚,JS小提琴是我离开的地方(只是搜索文本)但是根据我上面的解释:我正在尝试搜索RegE(也在上面链接)然后执行一个函数,然后替换它。 - jonshariat
好吧,如果你知道你要替换12,那么你可以做到 document.body.innerHTML = pageText.replace(/12/g, doSomething(12));。我希望我理解你的问题和目标。 - Incognito


这个应该为你做的:

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;
});

样本输入:

<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>

样本输出:

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

注意: 如果你需要,你可以通过改变来调整正则表达式 (?=\D\D) 一部分。


2
2018-03-09 13:09





你不需要使用 regex。 在里面拿价格 span 并为此范围添加一个类。由于span是内联元素,因此不会损害html设计。

我认为这将是更好的方法 regEx 

试试这样:

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));
  });

小提琴


1
2018-03-03 04:37



在原始问题中演示的值中添加$将返回NaN - BentOnCoding
@BentOnCoding:我在范围外添加$而不是价格。仔细看看 - Awlad Liton
为什么会被投票? - Awlad Liton
我认为这是最好的答案:) - Robin C Samuel


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演示

从理论上讲, $ 可以用在其值之前且其值使用的任何货币符号替换 . 作为小数点分隔符。

请注意,此处使用的正则表达式仅匹配前面带有美元符号的数字(例如 14.25 不会匹配)


1
2018-03-10 21:01





首先生成你的正则表达式。

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

生成与正则表达式匹配的字符串列表。

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

假设您要在HTML的所有主体上搜索正则表达式。

定义转换函数

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;
};

将每个匹配转换为结果。

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

虽然已经有其他答案可以完成你想要的东西,但我的答案总结了它你想要的方式


1
2018-03-15 22:26





(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);

如果你不关心价格重新格式化  小提琴


1
2018-03-15 00:13