java+添加分割符_如何给数字添加分隔符
编程时,我们有时可能需要对数字每3位⼀隔地添加逗号。在会计⾏业,这个专门术语叫"千位分隔符"。
每三位⼀隔是西⽅⼈的习惯,这样做的⽬的是便于读数。⽽且只对整数作千位分隔,⼩数部分不作分隔。
(不过,我觉得这种千位分隔符并不符合中国⼈的习惯,这样做反⽽不便于读数。)
由于⼩数部分是不作分隔的,所以,简单起见,我们在这⾥只讨论数据是整数的情况。
⾔归正传,怎么实现对数字每3位⼀隔地添加逗号呢?
① Java本⾝提供了⼀些函数可供使⽤,⽐如下列⽅式:
public static String formatNumber1( String num ){
num = placeAll(",", "");// 去掉所有逗号 DecimalFormat df = 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 = placeAll(",", ""); // 去掉所有逗号 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(",");
}
}
verse().toString();
}
采⽤这种⽅法,就不怕超长数据了。
④ 除了上述⽅法外,其实还有其他⽅法,⽐如采⽤正则表达式。
下⾯我就介绍⼏个⽤正则表达式来给超长数据添加分隔符的办法。
实现的代码如下:
public static String formatNumber3( String iniNum, int split ){ // 去掉所有逗号 String retNum = Patternpile(",").matcher( iniNum ).replaceAll("");
retNum += ","; // 末尾加个逗号,作為下列正則表達式的替換的基準 // 查这样的串:连续split位数字的串,其左边有个数字,其右边有个逗号 Pattern p = Patternpile("(?〈=\\d)(\\d{" + split + "})(?=,)");
for( Matcher m=p.matcher( retNum ); m.find(); ){ // 把这样的串替换为左边加逗号的串 retNum = m.replaceFirst(",$1");// 括号会记为变量,依次为$1,$2… m = p.matcher( retNum );// 替换后的串再次进⾏规则匹配,直到结束。 }
return Patternpile(",$").matcher( retNum ).replaceFirst("");
}
正则表达式是,简单地说,就是⼀种⽤来描述字符串⽂本的查和替换的规则。
可以理解为是⼀种字符串的查和替换的⼯具。
正则表达式被很多⾼级语⾔所⽀持,如Perl, Java, C#等, 甚⾄包括JavaScript。
不过,由于各种语⾔对正则表达式的理解及实现上有所差异,正则表达式也呈现各种流派或⽅⾔。
使⽤时,具体细节上会不相同,不⼀定能互相套⽤,这点要注意。
正则表达式具有"易写难读"的特点,可能不太好理解,所以,上述代码,我添加了很多注释。
上述数字串的匹配规则中,⽤到了"肯定逆序環視"和"肯定順序環視"。
环视的括号不会被记录成象$1这样的变量,它只是记录⼀个"位置",所以不会消耗掉串中的字符。
(?〈=…)的形式為肯定逆序環視,意思是: 某个位置,其左側符合…的条件
(?=...)的形式為肯定順序環視,意思是: 某个位置,其右側符合…的条件
此外,还有否定的环视。
(?〈!…)的形式為否定逆序環視,意思是: 某个位置,其左側不符合…的条件
(?!...)的形式為否定順序環視,意思是: 某个位置,其右側不符合…的条件
( 可能由于翻译的不同,有些地⽅,采⽤正向零宽断⾔,负向零宽断⾔之类的术语,其实是⼀个意思。)
正則表達式理论上是⽀持从右向左的查和替换的,但这还得靠宿主语⾔来实现。
但是,在Java中,似乎没实现,所以,在上述代码中,只能⽤循环来做了。
上述代码是前⼏天写的,还不够简洁。
今天在码这篇⽂章的时候,突然想到,可以把规则再适当修正⼀下,将肯定顺序环视改成否定顺序环视,
就不需要先在串尾添加逗号,然后在函数返回之前再去除逗号了。
⽴刻修改代码试了⼀下,果然可以。 ^_^
修改后的代码如下:
public static String formatNumber4( String iniNum, int split ){
String retNum = placeAll(",", ""); // 去掉所有的逗号 // 查这样的串:连续split位数字的串,其左側有个数字,其右側不是数字 Pattern p = Patternpile( "(?〈=\\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( placeAll(",", "") )
.reverse();// ① 去掉所有逗号,并把串倒过来。 // ② 替换这样的串:连续split位数字的串,其右边还有个数字,在串的右边添加逗号String retNum = Patternpile( "(\\d{" + split + "})(?=\\d)" )
.matcher( String() ).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 = place(/,/g,''); // 去掉所有的逗号 num += ","; // 末尾加⼀个逗号,作為下列正則表達式的替換的基準 for( var re = /(\d) (\d{3}\,)/; re.test( num ); ){
num = place( re, "$1\,$2" );
}
return num.substring( 0, num.length-1 );
}
function startup(){
alert( formatNumber6("-1234567890,1234567890,1234567890") );
}
没有环视功能的时候,只能靠在串末⼈为地先加上⼀个逗号来实现了。
还有⼀个⼩细节,在写Java函数的时候,我⽤了两个参数,第⼆个参数是⽤来确认是多少位进⾏分隔的。传3就3位⼀分隔,传4就4位⼀分隔,这样就更灵活了。
formatnumber数字格式
也许会计专业⼈⼠经过训练后,已经适应了这种西⽅⼈喜欢的千位分隔符。不过我是不习惯的。
我觉得,对中国⼈⽽⾔,更适合的应该是万位分隔符。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。

发表评论