编程时,我们有时可能需要对数字每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位一分隔,这样就更灵活了。

也许会计专业人士经过训练后,已经适应了这种西方人喜欢的千位分隔符。不过我是不习惯的。

我觉得,对中国人而言,更适合的应该是万位分隔符。

java+添加分割符_如何给数字添加分隔符相关推荐

  1. excel怎么添加换行符_在Excel公式中添加换行符

    excel怎么添加换行符 在Excel公式中添加换行符 (Add Line Break in Excel Formula) It's easy to add a line break when you ...

  2. android 手机号分段_android 手机号分段_android系统实现手机号添加分割符

    通过调用系统的PhoneNumberFormattingTextWatcher类来实现 ` import android.annotation.SuppressLint; import android ...

  3. word文档怎么给数字加千分符_怎样给Word添加千分符

    Word作为生活中常用的文本形式,有诸多用处,也有很多技巧,今天和大家分享的就是其中千分符的使用,千分符的效果是可以帮助我们在数字比较大,位数比较多的时候,对数字有个清晰直观的感受,快跟小编一起看看怎 ...

  4. JAVA如何分割出字符串中的数字?

    对于刚入门JAVA的小白来说没有指定的API来完成这个操作,只能靠自己的想法来区别字符与整数. 在我刚入门的时候突发奇想,既然JAVA中有字符串转整数的API,那为什么不可以利用呢.于是利用转换异常想 ...

  5. java mysql 占位符_在Java中编写带占位符的SQL语句

    C#中SQL中带占位符的语句 假设有一张学员信息表Student,通过表中的ID来找学员,查询的SQL语句如下 string sql = string.Format("select * fr ...

  6. java final修饰符_浅谈JAVA中的final修饰符

    final修饰符是JAVA中比较简单的一个修饰符,很多人通过书本就可以熟练掌握,但我学的时候,虽然感觉会用了,但是并不是十分理解这个修饰符,所以我找了相关资料,把我的个人理解分享给大家~~ final ...

  7. java项目添加功能失败_学生信息的添加 Java web简单项目初试(失败)

    题目要求: 1登录账号:要求由6到12位字母.数字.下划线组成,只有字母可以开头:(1分) 2登录密码:要求显示"• "或"*"表示输入位数,密码要求八位以上字 ...

  8. java split 分割字符串_字符串分割--java中String.split()用法

    在java.lang包中有String.split()方法,返回是一个数组. 一. "."和"|"都是转义字符,必须得加"\\"; 若是用& ...

  9. java string 占位符_驳《阿里「Java开发手册」中的1个bug》?

    前两天写了一篇关于<阿里Java开发手册中的 1 个bug>的文章,评论区有点炸锅了,基本分为两派,支持老王的和质疑老王的. 首先来说,无论是那一方,我都真诚的感谢你们.特别是「二师兄」, ...

  10. java swt 画按钮_向表中添加按钮(java swt)

    我正在尝试复制类似于此的UI: 我一直在关注如何创建表格每列中的按钮的作者说明(没有成功).我的项目与他的区别在于我正在尝试使用Tree而不是Table,而我正在使用eclipse TreeViewe ...

最新文章

  1. Python超越Java语言,跃居世界编程语言第2位了!你却还在犹豫学不学Python?
  2. linux实验串行端口程序设计,Linux下串口编程心得(转)
  3. 学生群体中奖励制度的马太效应
  4. PMON和SMON的功能
  5. jupyter怎么安装jieba_解决Jupyter无法导入已安装的 module问题
  6. 【C语言】计算器实现
  7. 中维高清监控录像被覆盖故障排除
  8. Lightingroom4_秋凉教程 P3-P31笔记
  9. 如何通过笔记本共享网络给台式
  10. excel表格如何转换成word表格_告诉你如何将excel表格转换成word文档
  11. 计算机组装与维护补考论文,计算机组装与维护课程教学论文
  12. html为知笔记模板,为知笔记,模板制作.doc
  13. android仿最新版本微信相册--附源码
  14. BiMap(HashBiMap,EnumBiMap,ImmutableBiMap)实战
  15. 画出使用分类器得到的决策边界
  16. 机器学习模型上线及优化流程
  17. Ubuntu 设置自动切换桌面壁纸
  18. 《Linux Kernel Development》读书笔记
  19. 你有价值,你的爱才有价值
  20. P1413 坚果保龄球——题解2020.10.10

热门文章

  1. Compose基础-SideEffect(二)
  2. 一个关于IT界牛人的故事,估计是杜撰的。
  3. 实习期间的一些思考整理(4)2018.4.14~4.16
  4. 服务器多个网站对应多个域名,多个域名指向同一个网站怎么样设置更合理?
  5. hdu4415 Assassin’s Creed (贪心)
  6. C/C++存储区域划分(栈区,堆区,全局区,代码区)
  7. 区域划分问题(数学题)
  8. Vue项目中实现改变屏幕尺寸重新刷新页面-计算页面尺寸
  9. web期末网站设计大作业:动漫网站设计——龙猫(10页) HTML+CSS+JavaScript 学生DW网页设计作业成品 web课程设计网页规划与设计 动漫漫画网页设计...
  10. 织梦dede源码列表页调用tags标签并带链接的实现方法