任意货币字符串 - 将所有零件分开?

时间:2011-08-19 03:02:08

标签: java currency number-formatting

我有100,00€$100.00100.00USD等货币的任意字符串(任意长度,地球上符号和ISO代码的任何有效货币)......(= like { {1}})。无法保证货币是正确的,可能是无效的符号或字符,也可能是错误的位置(在数字之前或之前)......

最简单的方法是什么:

  1. 整数部分
  2. 小数部分
  3. 货币(如果有效)
  4. 我知道100.000.000,00 EUR但是这个类只有在事先知道确切的语言环境并且似乎只能正确地设置格式化字符串时才有用...因为只返回数字,而不是货币..

    非常感谢! 马库斯

1 个答案:

答案 0 :(得分:6)

为了帮助回答这个问题,我们首先应该问一下,货币字符串是由什么组成的?

它包括:

  • 可选的货币符号(例如美元,欧元或美元)
  • 可选空格(使用Character.isSpaceCharCharacter.isWhitespace
  • 0到9之间的一个或多个数字,以句号或逗号分隔
  • 最后一段时间或逗号
  • 0到9之间的两位数字
  • 如果没有货币符号启动字符串,可选空格和货币符号

我将很快为这个问题创建一个具体的类,但是现在我希望这提供了一个起点 指向你。但请注意,正如我在评论中所解释的那样,某些货币符号(如$)无法唯一标识特定货币。

编辑:

万一其他人访问此页面并遇到同样的问题,我已经编写了下面的代码,更具体地回答了这个问题。以下代码属于公共领域。

/**
 * Parses a string that represents an amount of money.
 * @param s A string to be parsed
 * @return A currency value containing the currency,
 * integer part, and decimal part.
 */
public static CurrencyValue parseCurrency(String s){
    if(s==null || s.length()==0)
        throw new NumberFormatException("String is null or empty");
    int i=0;
    int currencyLength=0;
    String currency="";
    String decimalPart="";
    String integerPart="";
    while(i<s.length()){
        char c=s.charAt(i);
        if(Character.isWhitespace(c) || (c>='0' && c<='9'))
            break;
        currencyLength++;
        i++;
    }
    if(currencyLength>0){
        currency=s.substring(0,currencyLength);
    }
    // Skip whitespace
    while(i<s.length()){
        char c=s.charAt(i);
        if(!Character.isWhitespace(c))
            break;
        i++;
    }
    // Parse number
    int numberStart=i;
    int numberLength=0;
    int digits=0;
    //char lastSep=' ';
    while(i<s.length()){
        char c=s.charAt(i);
        if(!((c>='0' && c<='9') || c=='.' || c==','))
            break;
        numberLength++;
        if((c>='0' && c<='9'))
            digits++;
        i++;
    }
    if(digits==0)
        throw new NumberFormatException("No number");
    // Get the decimal part, up to 2 digits
    for(int j=numberLength-1;j>=numberLength-3 && j>=0;j--){
        char c=s.charAt(numberStart+j);
        if(c=='.' || c==','){
            //lastSep=c;
            int nsIndex=numberStart+j+1;
            int nsLength=numberLength-1-j;
            decimalPart=s.substring(nsIndex,nsIndex+nsLength);
            numberLength=j;
            break;
        }
    }
    // Get the integer part
    StringBuilder sb=new StringBuilder();
    for(int j=0;j<numberLength;j++){
        char c=s.charAt(numberStart+j);
        if((c>='0' && c<='9'))
            sb.append(c);
    }
    integerPart=sb.toString();
    if(currencyLength==0){
        // Skip whitespace
        while(i<s.length()){
            char c=s.charAt(i);
            if(!Character.isWhitespace(c))
                break;
            i++;
        }
        int currencyStart=i;
        // Read currency
        while(i<s.length()){
            char c=s.charAt(i);
            if(Character.isWhitespace(c) || (c>='0' && c<='9'))
                break;
            currencyLength++;
            i++;
        }
        if(currencyLength>0){
            currency=s.substring(currencyStart,
                    currencyStart+currencyLength);
        }
    }
    if(i!=s.length())
        throw new NumberFormatException("Invalid currency string");
    CurrencyValue cv=new CurrencyValue();
    cv.setCurrency(currency);
    cv.setDecimalPart(decimalPart);
    cv.setIntegerPart(integerPart);
    return cv;
}

它返回下面定义的CurrencyValue对象。

public class CurrencyValue {
@Override
public String toString() {
    return "CurrencyValue [integerPart=" + integerPart + ", decimalPart="
            + decimalPart + ", currency=" + currency + "]";
}
String integerPart;
/**
 * Gets the integer part of the value without separators.
 * @return
 */
public String getIntegerPart() {
    return integerPart;
}
public void setIntegerPart(String integerPart) {
    this.integerPart = integerPart;
}
/**
 * Gets the decimal part of the value without separators.
 * @return
 */
public String getDecimalPart() {
    return decimalPart;
}
public void setDecimalPart(String decimalPart) {
    this.decimalPart = decimalPart;
}
/**
 * Gets the currency symbol.
 * @return
 */
public String getCurrency() {
    return currency;
}
public void setCurrency(String currency) {
    this.currency = currency;
}
String decimalPart;
String currency;
}