Произвольная строка валюты - разделить все части? - PullRequest
3 голосов
/ 19 августа 2011

У меня есть произвольная строка с валютами, такими как 100,00€ или $100.00 или 100.00USD (произвольная длина, любая действительная валюта на земле, как символ и код ISO) ... (= как 100.000.000,00 EUR). Нет гарантии, что валюты верны, это может быть недопустимый символ или символ или неправильная позиция (после или перед номером) ...

Какой самый простой способ получить:

  1. Целая часть
  2. Десятичная часть
  3. Валюта (если действительная)

Я знаю о NumberFormat/CurrencyFormat, но этот класс полезен только в том случае, если вы заранее знаете точную локаль и, кажется, работаете только с правильно отформатированной строкой ... asw также возвращает только число, а не валюту ...

Большое спасибо! Markus

1 Ответ

6 голосов
/ 19 августа 2011

Чтобы помочь ответить на этот вопрос, мы должны сначала спросить, из чего состоит строка валюты?

Ну, это состоит из:

  • Необязательный символ валюты (например, USD, EUR или $)
  • Необязательный пробел (используйте Character.isSpaceChar или Character.isWhitespace)
  • Одна или несколько цифр от 0 до 9, разделенных точками или запятыми
  • Последний период или запятая
  • Две цифры от 0 до 9
  • Если строка валюты не начиналась, необязательный пробел и символ валюты

Я скоро создам конкретный класс для этого вопроса, но сейчас я надеюсь, что это даст старт точка для вас. Тем не менее, обратите внимание, что некоторые символы валюты, такие как $, не могут однозначно идентифицировать конкретную валюту без дополнительных, как я объяснил в своем комментарии.

Edit:

На тот случай, если кто-то еще посетит эту страницу и столкнется с той же проблемой, я написал код ниже, который более конкретно отвечает на вопрос. Код ниже находится в свободном доступе.

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