`
ithinkfeed
  • 浏览: 93328 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

如何给数字添加分隔符

阅读更多

 编程时,我们有时可能需要对数字每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不认,只能放弃了。有谁有办法的,也请告诉我,不胜感谢!^_^

  以上归纳了若干种给数字添加分隔符的办法,如果你在编程时碰到问题,希望本文能给你一些
启发和帮助。当然,也许还有更多更好的办法,欢迎讨论,共同提高。

分享到:
评论

相关推荐

    【JavaScript源代码】vue全局实现数字千位分隔符格式.docx

    在Vue.js中,为了使大数字更易于阅读,通常会使用千位分隔符格式化。这涉及到在数字字符串中插入逗号,以便每三位数字一组进行分隔。在提供的文档中,我们看到一个名为`numberToCurrency.js`的文件,它包含了一个名...

    给数字添加千分位分隔符.md

    本资源综合利用c语言的while循环, if条件判断, 函数递归调用等多种c语言知识,该算法采用传统的数位分离和字符数组,然后再用千分位分隔符进行插入。综合考虑,该算法对c语言初学者具有较大启发。

    C#千位分隔符

    在给定的代码片段中,我们看到一个名为`textBox1_KeyPress`的事件处理器,它在用户输入数字时动态地在数值中添加逗号作为千位分隔符。这里的关键逻辑是检查输入字符是否为数字(ASCII值在48到57之间),然后根据当前...

    jQuery数字格式化分隔符代码

    `jQuery数字格式化分隔符代码`提供了一种高效的方法,将大数字转换为更易读的形式,通过添加分隔符如逗号或空格来提高可读性。这个插件允许开发者自定义分隔符,满足不同场景的需求。 首先,我们来理解jQuery的核心...

    JS自动格式化输入的数字/千位分隔符.rar

    在JavaScript(JS)编程中,有时我们需要处理用户输入的数字,并将其格式化为更易读的形式,例如添加千位分隔符。这个“JS自动格式化输入的数字/千位分隔符.rar”压缩包提供的代码就是为了解决这个问题。在网页的...

    jquery数字格式化分隔符插件

    这个插件的主要功能是将长串的数字自动添加分隔符,如千位分隔符,以提高数字的可读性。默认情况下,分隔符通常为空格或逗号,但用户可以根据需求自定义分隔符号。 ### 插件安装与使用 使用`jquery-number-divider...

    js代码-JS给数字加千位分隔符

    在JavaScript(JS)中,给数字添加千位分隔符是一项常见的任务,它可以使大数字更易读。这种格式化通常用于财务报告、数据分析或任何显示大量数字的场景。千位分隔符通常是逗号(,)或者空格,使得数字的每个三位...

    数字加千分符和去千分符

    千分符(也称为分隔符)通常是一个逗号或句点,用于每三位数字之间,使得数字更易读。例如,数字1234567890经过千分符格式化后,会变为1,234,567,890。 在JavaScript中,我们可以使用内置的`toLocaleString()`方法...

    jQuery数字格式化分隔符代码.zip

    《jQuery数字格式化分隔符代码详解》 在网页开发中,我们经常遇到需要将大数字展示得更易读的情况,比如金额、人口数量等。这时,数字格式化分隔符就显得尤为重要。jQuery作为一款广泛使用的JavaScript库,提供了...

    【word 2016】使用了“分隔符”里面的下一页,造成空白页了怎么去掉?

    如果插入分隔符后没有立即添加任何内容,或者插入分隔符前后两部分内容之间存在较小的距离,那么这个新页就会呈现出空白状态,即所谓的“空白页”。 #### 二、解决问题的方法 针对上述问题,我们可以通过以下步骤...

    自定义带分隔符输入框CustomEditText

    - 在这个新类中,我们可以添加额外的属性,比如分隔符类型、位置等,通过`attr.xml`定义自定义属性,并在`build.gradle`中配置资源编译。 2. **监听输入事件**: - 为了在用户输入时实时插入分隔符,我们需要监听...

    2.Golang的基础语法(分隔符,注释,标识符,字符串拼接,空格)1

    本文将深入探讨四个主要概念:分隔符、注释、标识符以及字符串拼接,同时也会提及空格的使用。 首先,让我们来了解分隔符。与许多其他编程语言(如JAVA和PHP)不同,Golang不需要在每一行末尾添加英文分号(;)。这...

    Javascript 正则表达式实现为数字添加千位分隔符

    在本例中,通过“正则+replace”方法可以实现自动为数字添加千位分隔符。 首先,介绍如何使用正则表达式匹配数字并插入千位分隔符。在代码示例中,定义了一个名为`thousandBitSeparator`的函数,该函数接收一个数字...

    num2sepstr:num2str 千位分隔符-matlab开发

    这时,我们需要使用字符串处理函数来添加分隔符。一种方法是使用 `regexprep` 函数,它允许我们使用正则表达式来查找和替换模式。可以编写如下代码: ```matlab number = 123456789; strNum = num2str(number); ...

    Excel的千位分隔符是什么.docx

    因此,为了解决这一问题,Excel软件中引入了千位分隔符功能,它通过对数字进行格式化处理,每三位数字添加一个逗号,从而提高数字的可读性。在英语等语言环境中,这种做法尤为重要,因为它为用户提供了一种快速识别...

    使用您选择的千位分隔符格式化数字:通过添加千位分隔符将数字转换为更易读的格式的函数。-matlab开发

    通过添加千位分隔符将数字转换为更易读的格式的函数。 这个非常简单的函数允许您选择要返回的千位分隔符和小数位数。 任何字符(包括空格)都可以作为分隔符。 例如 千分之一(1234.567,',',1) 返回字符串'1,...

    jQuery数字格式化分隔符插件

    通过添加分隔符(如逗号或空格),可以显著提高数字的可读性。jQuery数字格式化插件正是为了解决这个问题而设计的。 这个插件允许开发者轻松地将大数字转换为具有分隔符的形式,例如,将"123456789"转换为"123,456,...

    android 每四个数字分隔输入框demo

    3. **添加分隔符**:在`afterTextChanged`方法中,我们检查当前文本的长度,如果长度为4的倍数且不是末尾,我们就插入一个分隔符(例如逗号)。同时,需要确保不重复添加分隔符。 ```java @Override public void ...

    java字符串类型数字设置千分位分隔

    它提供了丰富的功能,如设置数字的精度、添加千分位分隔符等。创建一个`DecimalFormat`实例后,我们可以使用`format()`方法将数字转换为字符串。 下面是一个简单的示例,展示了如何使用`DecimalFormat`设置千分位...

Global site tag (gtag.js) - Google Analytics