Arbitrary Currency String - Get all parts separated?

大城市里の小女人 提交于 2019-12-06 07:43:35

问题


I have arbitrary String with currencies like 100,00€ or $100.00 or 100.00USD (arbitrary lenght, any valid Currency on earth both Symbol and ISO-Code )...(=like 100.000.000,00 EUR). There is no guarantee that the currencies are correct, it might be an invalid Symbol or Character or at the wrong position (after or before the number)...

What is the easiest way to get:

  1. The integer part
  2. The decimal part
  3. The Currency (if valid)

I know of NumberFormat/CurrencyFormat but this class is only usefull if you know the exact locale in advance and seems to be working only to correctly formatted string... asw well only returns the number, not the currency...

Thank you very much! Markus


回答1:


To help answer this question we should first ask, what does a currency string consist of?

Well it consists of:

  • An optional currency symbol (such as USD, EUR, or $)
  • Optional white space (use Character.isSpaceChar or Character.isWhitespace)
  • One or more digits from 0 to 9, separated by periods or commas
  • A final period or comma
  • Two digits from 0 to 9
  • If no currency symbol started the string, optional white space and a currency symbol

I will soon create a concrete class for this question, but for now I hope this provides a starting point for you. Note, however, that some currency symbols such as $ cannot uniquely identify a particular currency without more, as I explained in my comment.

Edit:

Just in case someone else visits this page and encounters the same problem, I've written the code below that answers the question more concretely. The code below is in the public domain.

/**
 * 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;
}

It returns a CurrencyValue object defined below.

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;
}


来源:https://stackoverflow.com/questions/7116507/arbitrary-currency-string-get-all-parts-separated

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!