繁体   English   中英

使用replace和正则表达式应用货币格式

[英]Applying currency format using replace and a regular expression

我正在尝试理解一些将数字转换为货币格式的代码。 因此,如果您有16.9,它将转换为$ 16.90。 代码的问题是,如果您的金额超过$ 1,000,则只返回$ 1,金额超过$ 2,000则返回$ 2,依此类推。数百元的金额显示罚款。

这是函数:

var _formatCurrency = function(amount) {
    return "$" + parseFloat(amount).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,')
};

(分号放在方括号后面的原因是因为此函数本身是另一个函数的声明。该函数与本讨论无关。)

我发现最初将代码放入其中的人在某个地方找到了它,但并没有完全理解它,也没有测试这种特殊情况。 我自己对正则表达式的处理不多。 我不仅在尝试修复它,而且还在理解它的工作原理。

这是我发现的。 开括号后的反斜杠和g之前的反斜杠之间的代码是模式。 g表示全局搜索。 \\d表示数字,而(?=\\d{3})+\\. 似乎表示找到3位数字加一个小数点。 不过,我不确定我是否正确,因为如果正确,它是否不应该忽略5.4之类的数字? 很好 另外,我不确定'$1,'是干什么的。 在我看来,它应该放在数字的位置,但是那不将所有数字都更改为$ 1吗? 另外,为什么在1之后会有逗号?

假设您只使用美元,那么这应该可以代替正则表达式。 我还进行了一些测试,以验证它是否正常运行。

 var test1 = '16.9'; var test2 = '2000.5'; var test3 = '300000.23'; var test4 = '3000000.23'; function stringToUSD(inputString) { const splitValues = inputString.split('.'); const wholeNumber = splitValues[0].split('') .map(val => parseInt(val)) .reverse() .map((val, idx, arr) => idx !== 0 && (idx + 1) % 3 === 0 && arr[idx + 1] !== undefined ? `,${val}` : val) .reverse() .join(''); return parseFloat(`${wholeNumber}.${splitValues[1]}`).toFixed(2); } console.log(stringToUSD(test1)); console.log(stringToUSD(test2)); console.log(stringToUSD(test3)); console.log(stringToUSD(test4)); 

该模式无效,并且您对该功能的理解不正确。 此函数以标准美元格式格式化数字,其工作方式如下:

  1. parseFloat()函数将字符串值转换为十进制数。
  2. toFixed(2)函数将十进制数字四舍五入到小数点后的两位数。
  3. 这里的replace()函数用于添加数千个spearator(即,每3位数字后的逗号)。 该模式不正确,因此这是建议的修复程序/(\\d)(?=(\\d{3})+\\.)/g ,这是它的工作方式:
    • (\\d)捕获一个数字。
    • (?=(\\d{3})+\\.)称为前瞻,它确保上面捕获的数字包含一组3位数字(\\d{3})或更多+后跟小数点\\. 之后是小数点。
    • g标志/修饰符将全局应用模式,即在整个数量上。
    • 替换$1,将模式替换为第一个捕获的组$1 ,在本例中为数字(\\d) (所以从技术上讲,用数字本身替换数字以确保我们不会在替换中丢失该数字),然后跟一个逗号, 就像我说的,这只是添加千位分隔符。

这是一些建议修复的测试。 请注意,它可以很好地与数字和字符串配合使用:

 var _formatCurrency = function(amount) { return "$" + parseFloat(amount).toFixed(2).replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,'); }; console.log(_formatCurrency('1')); console.log(_formatCurrency('100')); console.log(_formatCurrency('1000')); console.log(_formatCurrency('1000000.559')); console.log(_formatCurrency('10000000000.559')); console.log(_formatCurrency(1)); console.log(_formatCurrency(100)); console.log(_formatCurrency(1000)); console.log(_formatCurrency(1000000.559)); console.log(_formatCurrency(10000000000.559)); 

关于你的评论

我希望只编辑正则表达式,使其正常工作。

您当前使用的正则表达式显然对您不起作用,因此我认为您应该考虑替代方法,即使它们不太相似,并且

尝试使代码更改尽可能小

可以理解,但是有时使用比紧凑和象形的代码更大,更易读的代码更好。

重新营业:

我假设您正在获取一个字符串作为参数,并且该字符串仅由数字组成,并且在最后1或2个数字之前可能没有点。 就像是

//input     //intended output
1           $1.00
20          $20.00
34.2        $34.20
23.1        $23.10
62516.16    $62,516.16
15.26       $15.26
4654656     $4,654,656.00
0.3         $0.30

我将让您对1之类的(假设的)非有效值进行预检查 2.2。 | .6 | 4.8.1 | 4.856 |

建议的解决方案:

var _formatCurrency = function(amount) {
    amount = "$" + amount.replace(/(\d)(?=(\d{3})+(\.(\d){0,2})*$)/g, '$1,');

    if(amount.indexOf('.') === -1)
        return amount + '.00';

    var decimals = amount.split('.')[1];

    return decimals.length < 2 ? amount + '0' : amount;
};

正则表达式细分:

  • (\\d) :匹配一位数字。 括号将事物分组以在需要时进行引用。

  • (?=(\\d{3})+(\\.(\\d){0,2})*$) 现在这个家伙。 从头到尾:

    • $ :匹配字符串的结尾。 这样一来,您就可以从头开始匹配而不是从头开始匹配,这对于添加逗号非常方便。
    • (\\.(\\d){0,2})* :这部分处理点和小数。 \\. 匹配点。 (\\d){0,2}匹配0、1或2位数字(十进制)。 *表示整个组可以为空。
    • ?=(\\d{3})+\\d{3}精确匹配3位数字。 +表示至少出现一次 最后, ?=匹配主表达式后的组,但不将其包括在结果中。 在这种情况下,一次需要输入三位数(从头到尾还记得吗?),并且在替换时将其排除在结果之外。
    • g :全局匹配并替换整个字符串。
  • 替换为$1, ,:这是引用捕获的组进行替换的方式,在这种情况下,所需组为1 由于该模式将匹配位置3n + 1中的每个数字(从末尾或点开始)并将其捕获到组号1(\\d) )中,然后用$1,替换该捕获$1,将在后面有效地添加一个逗号每次捕获。

试试看,请反馈。

另外,如果您还没有这样做的话(那么SO并没有给我提供足够的格式来强调这一点),那么真的可以像Taplar所建议的那样浏览 该网站

好的,我想向所有回答的人道歉。 我进行了一些进一步的跟踪,发现引入的JSON调用实际上确实包含逗号,因此它只是解析该第一位数字。 当我认为代码中没有逗号时,我在代码中的错误位置进行了查找。 我非常感谢大家的投入,并希望您不会因为在整个练习之前不了解我而感到不好。 如果没有别的,至少我现在知道该正则表达式的运行方式,以便将来我可以使用它。 现在,我只需要删除该逗号。

祝你有美好的一天!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM