编程时,我们有时可能需要对数字每3位一隔地添加逗号。在会计行业,这个专门术语叫"千位分隔符"。
每三位一隔是西方人的习惯,这样做的目的是便于读数。而且只对整数作千位分隔,小数部分不作分隔。
(不过,我觉得这种千位分隔符并不符合中国人的习惯,这样做反而不便于读数。)
由于小数部分是不作分隔的,所以,简单起见,我们在这里只讨论数据是整数的情况。
言归正传,怎么实现对数字每3位一隔地添加逗号呢?
① Java本身提供了一些函数可供使用,比如下列方式:
public static String formatNumber1( String num ){
num = num.replaceAll(",", ""); // 去掉所有逗号
java.text.DecimalFormat df = new java.text.DecimalFormat("##,###,###");
return df.format( Double.parseDouble( num ) );
}
当然,还有其他的函数可供使用,这里就不举例了。
这么做有个缺点,当数字很大时,转换就会出错了。
比如,1234567890123456789 会变成1,234,567,890,123,456,770
这样的数据显然不是我们想要的。
② 此外,一些数据库(比如Oracle)也提供了数字的添加分隔符的方法。
SELECT
TO_CHAR( TO_NUMBER('12345678901234567890'), 'FM999,999,999,999,999,999,999' )
AS JIN_E
FROM
DUAL
这种方法在从数据库中取数据直接显示在页面上时很有用,因为不需要再通过Java循环来添加分隔符了。
但,有个地方要注意:
在程序中,拼SQL语句时,必须要保证FM999,999,999,999,999,999,999这个串中
的9的个数要多余传入的变量的值的数字的个数。否则就得不到正确的值,得到的是一串
#############。
③ 还是回到Java,在①的方法中,已经提到,这种方法只在数字不是特别大时有效,
当数字很大时,将返回一个不正确的数据。
那么,如何对超长数据添加分隔符呢?
一般,很容易想到用字符串循环的方式来添加,比如象下面这样的代码:
public static String formatNumber2( String num ){
num = num.replaceAll(",", ""); // 去掉所有逗号
StringBuffer ret = new StringBuffer();
for( int i = num.length()-1; i≥0; i-- ){
ret.append( num.charAt(i) );
if( (num.length()-i)%3==0 ){
ret.append(",");
}
}
return ret.reverse().toString();
}
采用这种方法,就不怕超长数据了。
④ 除了上述方法外,其实还有其他方法,比如采用正则表达式。
下面我就介绍几个用正则表达式来给超长数据添加分隔符的办法。
实现的代码如下:
public static String formatNumber3( String iniNum, int split ){
// 去掉所有逗号
String retNum = Pattern.compile(",").matcher( iniNum ).replaceAll("");
retNum += ","; // 末尾加个逗号,作為下列正則表達式的替換的基準
// 查找这样的串:连续split位数字的串,其左边有个数字,其右边有个逗号
Pattern p = Pattern.compile("(?〈=\\d)(\\d{" + split + "})(?=,)");
for( Matcher m=p.matcher( retNum ); m.find(); ){
// 把这样的串替换为左边加逗号的串
retNum = m.replaceFirst(",$1"); // 括号会记为变量,依次为$1,$2…
m = p.matcher( retNum ); // 替换后的串再次进行规则匹配,直到结束。
}
return Pattern.compile(",$").matcher( retNum ).replaceFirst("");
}
正则表达式是,简单地说,就是一种用来描述字符串文本的查找和替换的规则。
可以理解为是一种字符串的查找和替换的工具。
正则表达式被很多高级语言所支持,如Perl, Java, C#等, 甚至包括JavaScript。
不过,由于各种语言对正则表达式的理解及实现上有所差异,正则表达式也呈现各种流派或方言。
使用时,具体细节上会不相同,不一定能互相套用,这点要注意。
正则表达式具有"易写难读"的特点,可能不太好理解,所以,上述代码,我添加了很多注释。
上述数字串的匹配规则中,用到了"肯定逆序環視"和"肯定順序環視"。
环视的括号不会被记录成象$1这样的变量,它只是记录一个"位置",所以不会消耗掉串中的字符。
(?〈=…)的形式為肯定逆序環視,意思是: 某个位置,其左側符合…的条件
(?=...)的形式為肯定順序環視,意思是: 某个位置,其右側符合…的条件
此外,还有否定的环视。
(?〈!…)的形式為否定逆序環視,意思是: 某个位置,其左側不符合…的条件
(?!...)的形式為否定順序環視,意思是: 某个位置,其右側不符合…的条件
( 可能由于翻译的不同,有些地方,采用正向零宽断言,负向零宽断言之类的术语,其实是一个意思。)
正則表達式理论上是支持从右向左的查找和替换的,但这还得靠宿主语言来实现。
但是,在Java中,似乎没实现,所以,在上述代码中,只能用循环来做了。
上述代码是前几天写的,还不够简洁。
今天在码这篇文章的时候,突然想到,可以把规则再适当修正一下,将肯定顺序环视改成否定顺序环视,
就不需要先在串尾添加逗号,然后在函数返回之前再去除逗号了。
立刻修改代码试了一下,果然可以。 ^_^
修改后的代码如下:
public static String formatNumber4( String iniNum, int split ){
String retNum = iniNum.replaceAll(",", ""); // 去掉所有的逗号
// 查找这样的串:连续split位数字的串,其左側有个数字,其右側不是数字
Pattern p = Pattern.compile( "(?〈=\\d)(\\d{"+split+"})(?!\\d)" );
for( Matcher m=p.matcher( retNum ); m.find(); ){
retNum = m.replaceFirst(",$1");
m = p.matcher( retNum );
}
return retNum;
}
现在,只剩下一个小小的遗憾,就是那个循环了。
不过,也可能Java中有从右向左查找的参数,只是我不知道而已,有谁知道的,请告诉我,不胜感谢!^_^
⑤ 尽管Java看起来似乎不支持正则表达式的从右向左的查找和替换。
那么碰到这种情况,循环是不是就一定不可避免了呢。
其实,如果换个思路,我们自己把串给倒过来,就不需要那个循环了,用正则表达式一下子就搞定了。
实现的代码如下:
public static String formatNumber5( String iniNum, int split ){
StringBuffer tmp = new StringBuffer().append( iniNum.replaceAll(",", "") )
.reverse(); // ① 去掉所有逗号,并把串倒过来。
// ② 替换这样的串:连续split位数字的串,其右边还有个数字,在串的右边添加逗号
String retNum = Pattern.compile( "(\\d{" + split + "})(?=\\d)" )
.matcher( tmp.toString() ).replaceAll("$1,");
// ③ 替换完后,再把串倒回去返回
return new StringBuffer().append( retNum ).reverse().toString();
}
哈哈,没有循环,三步搞定!
⑥ 上面已经提到,javaScript也提供了对正則表達式的支持。
有点遗憾的是,javaScript中没有提供正則表達式的环视功能。
不过没关系,不用环视,我们一样可以实现给数字添加分隔符的。
下面给出javaScript的代码。( 可以参照比对④中的Java代码。)
〈html〉
〈head〉
function formatNumber6( num ){
if( !num.match(/^([0-9]|-)[0-9,]*$/) ){ // 数字或负号开头,后续数字或逗号的文字串
return num; // 数字不匹配
}
num = num.replace(/,/g,''); // 去掉所有的逗号
num += ","; // 末尾加一个逗号,作為下列正則表達式的替換的基準
for( var re = /(\d)(\d{3}\,)/; re.test( num ); ){
num = num.replace( re, "$1\,$2" );
}
return num.substring( 0, num.length-1 );
}
function startup(){
alert( formatNumber6("-1234567890,1234567890,1234567890") );
}
window.onload = startup;
〈/head〉
〈/html〉
没有环视功能的时候,只能靠在串末人为地先加上一个逗号来实现了。
还有一个小细节,在写Java函数的时候,我用了两个参数,第二个参数是用来确认是多少位进行分隔的。
传3就3位一分隔,传4就4位一分隔,这样就更灵活了。
也许会计专业人士经过训练后,已经适应了这种西方人喜欢的千位分隔符。不过我是不习惯的。
我觉得,对中国人而言,更适合的应该是万位分隔符。
在javaScript中,正则表达式是用两条斜线中间加表达式内容来表示的,这点和Java不同。
Java用的是双引号。结果因为这个的缘故,我就没办法传入分隔多少位的参数了,我试了
很多次,但JavaScript不认,只能放弃了。有谁有办法的,也请告诉我,不胜感谢!^_^
以上归纳了若干种给数字添加分隔符的办法,如果你在编程时碰到问题,希望本文能给你一些
启发和帮助。当然,也许还有更多更好的办法,欢迎讨论,共同提高。
分享到:
相关推荐
vue全局实现数字千位分隔符格式 本文实例为大家分享了vue全局实现数字千位分隔符格式的具体代码,供大家参考,具体内容如下 这个是啥意思呢 ? 就是我们在页面上需要渲染数据的时候,比如 88888,我们需要按照...
本资源综合利用c语言的while循环, if条件判断, 函数递归调用等多种c语言知识,该算法采用传统的数位分离和字符数组,然后再用千分位分隔符进行插入。综合考虑,该算法对c语言初学者具有较大启发。
js代码-JS给数字加千位分隔符
鼠标onfous把数字转化为带千分符,移走再给数字加千分符
通过添加千位分隔符将数字转换为更易读的格式的函数。 这个非常简单的函数允许您选择要返回的千位分隔符和小数位数。 任何字符(包括空格)都可以作为分隔符。 例如 千分之一(1234.567,',',1) 返回字符串'1,...
在项目中做货币转换的时候经常需要可以实现自动格式化输入的数字,自动千位分隔符,在网上也看到一些其他网友的实现的代码,感觉都不是太满意,于是自己研究了下,分享给大家。
数字分隔符 第四阶段 这是一个,它是将其早期草案与 Christophe Porteneuve 的-numeric 合并的结果,以扩展现有的以允许数字之间的分隔符。 致谢 该提案目前由@samuelgoto、@rwaldron 和@leobalter 支持。 该提案...
对输入数字调用 num2str(使用可选的指定格式)并添加逗号作为千位分隔符。
一个为数字值添加千位分隔符的程序包。 例子 var bh = require ( 'bullhead' ) ; console . log ( bh ( 12000 ) ) ; // 12,000 console . log ( bh ( 12000 , 2 ) ) ; // 12,000.00 console . log ( bh ( ...
一个基本的 / 过滤器,可以为一个数字添加数千个分隔符。 ##安装 要安装,请将thousands-separated-filter.rb _plugins文件复制到您的 Jekyll _plugins文件夹中。 ##用法 {{ varname | thousands_separated }...
在JS中,我们可以使用toLocaleString()方法来实现数字的千分位格式化处理,该方法可以将数字转换为字符串,然后添加逗号分隔符。例如: ```javascript var num = 1450068; console.log(num.toLocaleString()); // 1,...
数据格式不正确时会给出提示,有或者没有逗号(千位分隔符)的格式都可以检测。 将压缩文件解压到Macro文件夹,在EmEditor中添加该脚本后就可以使用了。 相比Excel,这个脚本可以直接对一段文字中的数字求和,而且...
2. 二进制文字和数字分隔符 C++ 程序员现在可以创建一个二进制数字,向已经包含十进制,十六进制以及很少使用的八进制的标准中又添加了一员。二进制数字使用前缀0b后面紧接数字。在美国和英国,我们使用逗号来作为...
数字分隔符 为了提高数字的可读性,您可以使用下划线作为分隔符: const largeNumber = 1_000_000_000; console.log(largeNumber); // 1000000000 3. 事件监听器只运行一次 如果你想添加一个事件监听器并且只...
千位分隔符JavaScript / jQuery中数字的定界符。 可以轻松配置以满足特定的本地化需求。 在演示指示: 添加对js文件的引用。 通过javascript或jQuery调用插件:$(selector).thousanddelimiterjs(); 每个元素可以...
千位分隔符 API 简单 支持增加和降低动画 Usage // 设置最终值,开始动画 mNumberAnimTextView.setNumberString("98765432.75"); Option // 设置前缀 mNumberAnimTextView.setPrefixString("¥"); // 设置后缀 ...
主要介绍了vue element-ui实现input输入框金额数字添加千分位,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
在前面的评论中,我已经组装了一个灵活的验证系统的粗略实现。 您可以轻松地为自定义消息添加处理程序,该处理程序将允许您在运行时更改所需的分隔符,以响应主程序收到的WM_SETTINGCHANGE消息。