一个简单的正则表达式解决方案,用于在 javascript 中进行数字分组和验证

Posted

技术标签:

【中文标题】一个简单的正则表达式解决方案,用于在 javascript 中进行数字分组和验证【英文标题】:A simple regex solution for digit grouping and validation in javascript 【发布时间】:2017-12-13 15:57:52 【问题描述】:

我需要使用 javascript 在小数点两侧(整体和小数部分)对数字进行分组(添加千位分隔符)。我研究了使用正则表达式是否可以在没有太多复杂性的情况下实现这一点。

网上提供的解决方案似乎专注于对整数进行分组或仅对小数点左侧进行分组,因此我尝试提出自己的解决方案,包括验证正则表达式...

【问题讨论】:

你想出了什么,你能给我们举例说明输入和他们的预期输出吗? @ctwheels 我没有在问题中包含示例输入和输出,因为我已经在答案中发布了示例,但是如果可以编辑问题,我可以在问题以及......我认为答案足以解释。 (这是一个问答对) 知道了,结果应该是小数点后的镜像分隔符吗? @ctwheels 我不太清楚镜像分隔符是什么意思,但是分隔符在小数点两边要相同,并且分隔符的位置应该在感觉应该从小数点开始往外数,每隔三位数放置分隔符... 我已为您的问题添加了答案。它提供了比现有代码更简单的正则表达式和方法。希望对您有所帮助! 【参考方案1】:

sn-p 中的代码仅使用给定的验证正则进行测试,因此如果不正确,则测试结果将无效...

function addThousandsSeparators(n) 
  return n.toString().replace(/-?\d+?(?=(?:\d3)+(?:\D|$))/gy, '$&,').replace(/\d3(?=\d)/g, '$&,')


function validateThousandsSeparators(n) 
  return /^-?\d1,3(?:,\d3)*(?:\.(?:\d3,)*\d1,3)?$/.test(n)


var tests = [
  0,
  1,
  1.1,
  1.0123456789,
  -10.012345678,
  210.01234567,
  -3210.0123456,
  43210.012345,
  -543210.01234,
  6543210.0123,
  -76543210.012,
  876543210.01,
  -9876543210.1,
  1,
  10,
  -210,
  -3210,
  43210,
  543210,
  -6543210,
  -76543210,
  876543210,
  9876543210,
  0.0123456789,
  .012345678,
  -0.01234567,
  -.0123456,
  0.012345,
  .01234,
  -0.0123,
  -.012,
  0.01,
  .1
]
, i

function test(n) 
  n = addThousandsSeparators(n)
  console.log(
    (
      validateThousandsSeparators(n) ?
        'valid:   ' : 'invalid: '
    ) + n
  )


for(i of tests)
  test(i)

【讨论】:

为什么不直接使用console.log 而不是复杂的自定义日志? @ThejakaMaldeniya sn-ps 左侧有复选框Show console【参考方案2】:

简介

请注意,输出是 OP 所期望的。输出的小数点应反映整数分隔符,使1234.1234 变为1,234.123,4不是 1,234.1,234。对于这个相反的效果(1,234.1,234的格式),请直接在下面展开运行sn -p。

var nums = [ 0, 1, 1.1, 1.0123456789, -10.012345678, 210.01234567, -3210.0123456, 43210.012345, -543210.01234, 6543210.0123, -76543210.012, 876543210.01, -9876543210.1, 1, 10, -210, -3210, 43210, 543210, -6543210, -76543210, 876543210, 9876543210, 0.0123456789, .012345678, -0.01234567, -.0123456, 0.012345, .01234, -0.0123, -.012, 0.01, .1 ];

nums.forEach(function(n)
  console.log(addSeparators(n));
);

function addSeparators(n) 
  var regex = /\d3(?![-.]|$)/g;
  var replace = `$&,`;
  n = n.toString();
  n = reverseNumber(n).replace(regex, replace);
  return reverseNumber(n);


function reverseNumber(n) 
  return n.split("").reverse().join("");

代码

下面的代码提供了一个简单的正则表达式和添加分隔符的方法。字符串首先反转以将分隔符添加到整数部分,然后再次反转以将分隔符添加到小数部分。

var nums = [ 0, 1, 1.1, 1.0123456789, -10.012345678, 210.01234567, -3210.0123456, 43210.012345, -543210.01234, 6543210.0123, -76543210.012, 876543210.01, -9876543210.1, 1, 10, -210, -3210, 43210, 543210, -6543210, -76543210, 876543210, 9876543210, 0.0123456789, .012345678, -0.01234567, -.0123456, 0.012345, .01234, -0.0123, -.012, 0.01, .1 ];

nums.forEach(function(n)
  console.log(addSeparators(n));
);

function addSeparators(n) 
  var regex = /\d3(?=[^.,]+$)(?!-)/g;
  var replace = `$&,`;
  n = n.toString();
  n = reverseNumber(n).replace(regex, replace);
  n = reverseNumber(n).replace(regex, replace);
  return n;


function reverseNumber(n) 
  return n.split("").reverse().join("");

说明

\d3 准确匹配一个数字 3 次 (?=[^.,]+$) 确保此处和行尾之间不存在小数点或分隔符(防止重复的分隔符并确保它只处理 . 之后的字符串部分) (?!-) 确保后面的不是负号(例如,这可以防止 -543210.01234 变为 -,543,210.012,34

【讨论】:

感谢@ctwheels 的回答。我查看了您的解决方案,发现正则表达式也可以写为 /\d3(?=[^.,-]+-?$)/g 或 /\d 3(?=\d+-?$)/g 消除负前瞻。顺便说一句,您是否决定在这一点上反转而不是拆分,以便可以重用相同的正则表达式?我不确定拆分、反转两次和重新加入是否会对性能产生影响,但如果该函数不用于处理大型数据集,这并不是特别值得关注的问题,并且解决方案足够简单,解释将是对读者有用...

以上是关于一个简单的正则表达式解决方案,用于在 javascript 中进行数字分组和验证的主要内容,如果未能解决你的问题,请参考以下文章

Java 正则简单用法

实现简单正则表达式的建议(用于 bbcode/geshi 解析)

正则表达式匹配不适用于 Pyteomics 解析器的简单字符串

Go 语言入门很简单:正则表达式

简单的js正则表达式问题

什么是用于查找未注释 Java 代码行的正则表达式?