2012-06-05 8 views
0

문자열 목록이 있는데 패턴이 일치하면 문자열을 부동으로 변환하고 싶습니다. 여기 형식이 지정된 문자열을 부동으로 변환하는 방법은 무엇입니까?

는 어떤 가치와 예상되는 결과이다 : 그 내가 옆에

Pattern pattern = Pattern.compile("#.###,###"); 
for(String s : list){ 
    Matcher m = pattern.matcher(s); 
    if(m.matches()){ 
     //convert 
    } 
} 

'나는 번호가 유효한지 확인하기 위해이 코드를하려고했으나 패턴이 일치되지 않습니다

1000   -> 1000.0 
1.000  -> 1000.0 
1.000,000 -> 1000.0 
-1.000,000 -> -1000.0 
9,132  -> 9.132 
1,000.00  -> invalid 
30.10.2010 -> invalid 
1,000.000,00 -> invalid 

이 코드를 사용해 보았습니다 :

DecimalFormat df = (DecimalFormat) NumberFormat.getCurrencyInstance(); 
for(String s : list){ 
     try { 
      Number num = df.parse(s); 
      //.. 
     } catch (ParseException e) { 

     } 
    } 

이 코드의 문제점은 패턴 기반 v 알리아스가 수행됩니다. 예 : 2012/05/30과 같은 날짜는 2012으로 변환됩니다.

그렇다면 올바른 패턴을 정의하거나 내 요구에 DecimalFormat을 어떻게 구성 할 수 있습니까?

답변

2

나는 이것이 당신이 원하는 생각합니다. 의견은 그것을 설명해야합니다.

@Test 
public void testAllValues() { 
    testValue("1000", "1000"); 
    testValue("1.000,000", "1000"); 
    testValue("-1.000,000", "-1000"); 
    testValue("9,132", "9.132"); 
    testValue("1,000.00", null); 
    testValue("30.10.2010", null); 
    testValue("1,000.000,00", null); 
} 

private void testValue(String germanString, String usString) { 
    BigDecimal germanDecimal = (BigDecimal) parse(germanString); 
    if (usString != null) { 
     BigDecimal usDecimal = new BigDecimal(usString); 
     assertEquals("German " + germanString + " did not equal US " + usString, 0, germanDecimal.compareTo(usDecimal)); 
    } else { 
     assertEquals("German " + germanString + " should not have been pareseable", null, germanDecimal); 
    } 
} 

public BigDecimal parse(String s) { 
    // Patch because parse doesn't enforce the number of digits between the 
    // grouping character (dot). 
    if (!Pattern.matches("[^.]*(\\.\\d{3})*[^.]*", s)) { 
     return null; 
    } 

    DecimalFormat df = (DecimalFormat) DecimalFormat.getInstance(Locale.GERMANY); 
    df.setParseBigDecimal(true); 

    // Have to use the ParsePosition API or else it will silently stop 
    // parsing even though some of the characters weren't part of the parsed 
    // number. 
    ParsePosition position = new ParsePosition(0); 
    BigDecimal parsed = (BigDecimal) df.parse(s, position); 

    // getErrorIndex() doesn't seem to accurately reflect errors, but 
    // getIndex() does reflect how far we successfully parsed. 
    if (position.getIndex() == s.length()) { 
     return parsed; 
    } else { 
     return null; 
    } 
} 
3

Pattern 클래스는 정규식과 함께 작동합니다.

Pattern pattern = Pattern.compile("-?\d\.\d{1,3}(,\d{1,3})?"); 

당신은 아마 당신이 원하는 또는 일치하지 않는 형식을 정확히에 따라 조정이 정규식을 원하는 : 당신은 아마이 원하는.

1

System.out.println("1,000.000,00".matches("^[+-]?\\d+(\\.\\d{3})*(,\\d+)?")); 

내가 전화 번호로 시작 + 그래서 그냥 케이스에 추가 할 수 있는지 확실하지 않다보십시오. 또한 0100000.000.000,1234가 유효해야하는지 여부도 알 수 없습니다. 이유를 알지 못하면 정규식이 수정 될 것입니다.

+0

엄밀히 말하면, 언급 한 숫자가 유효하지 않아야하지만 그런 숫자가 나타날 것으로 기대하지는 않습니다. 그래서 현재 내 목록을 필터링하는 데는 잘 작동합니다. 귀하의 정규식을 사용하여 문자열을'DecimalFormat'을 사용하여 변환 할 수 없습니다. 왜냐하면 정규식을 변경하면 형식이 더 이상 올바르지 않을 수 있기 때문입니다. 그래서 거기에 정규식을 기반으로 문자열을 변환하는 방법은 무엇입니까? – Pedro

+0

@Pedro'DecimalFormat'을 사용한 적은 한번도 없기 때문에 도움이되지 않습니다. 죄송합니다. 이제 내가 할 수있는 일은 필요할 경우 정규식을 더 커스터마이징하는 것입니다. – Pshemo

0

패턴이 쉼표 시도 인 경우 :

String[] splitted = string.split(",") 

size of splitted > 2 경우 -> 무효가.

splitted.size == 2 && splitted[1].split(".") > 0 -> 또한 잘못되었습니다.

형식이 괜찮 으면 -> 모든 점을 제거하고 쉼표를 포인트로 바꾸고 쉼표 뒤의 문자열을 int로 구문 분석하고 조각을 연결하십시오.

매우 간단한 방법이지만 작동 ...