[英]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));
该模式无效,并且您对该功能的理解不正确。 此函数以标准美元格式格式化数字,其工作方式如下:
parseFloat()
函数将字符串值转换为十进制数。 toFixed(2)
函数将十进制数字四舍五入到小数点后的两位数。 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.