Wyciąganie samych liczb - wyrażenie regularne

Wyciąganie samych liczb - wyrażenie regularne
GC
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 249
0

Dlaczego moje wyrażenie na radzi sobie z pozbyciem się litery "a" z takiego tekstu: "a899.00";

Kopiuj
 
    private Double findNumberInString(String text) {
        StringBuffer sBuffer = new StringBuffer();
        Pattern p = Pattern.compile("[0-9]+.[0-9]*|[0-9]*.[0-9]+|[0-9]+");
        Matcher m = p.matcher(text);
        while (m.find()) {
            sBuffer.append(m.group());

        }
        System.out.println(sBuffer);
        return Double.parseDouble(sBuffer.toString());
    }
Kopiuj
Exception in thread "main" java.lang.NumberFormatException: For input string: "a899.00"
a899.00
	at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
	at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
	at java.lang.Double.parseDouble(Double.java:538)
	at PhonesDownloader.findNumberInString(PhonesDownloader.java:126)
	at PhonesDownloader.convertToList(PhonesDownloader.java:71)
	at Main.main(Main.java:27)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
  • Rejestracja: dni
  • Ostatnio: dni
2

Nie poradzi sobie ponieważ:

[0-9]+.[0-9]|[0-9].[0-9]+|[0-9]+

pierwszy or (|) można rozpisać tak:

[0-9]+.[0-9]* OR [0-9]*.[0-9]+|[0-9]+

Poza tym wyrażenie jest i tak bardzo źle napisane. Osiągniesz swój efekt jeśli zrobisz tak:

[0-9]+(.[0-9]|[0-9]).[0-9]+|[0-9]+

Ale to wyrażenie też jest bardzo niepoprawne. Kropka jest znakiem znaczącym w regexpach i powinna być escapowana.

ŁF
  • Rejestracja: dni
  • Ostatnio: dni
2

Nakomplikowałeś. Użyj jakiegoś testera wyrażeń regularnych online, np. http://java-regex-tester.appspot.com/.
Literka na początku łapie się, ponieważ pasuje do reguły [0-9]*.[0-9]+ - nie wyeskejpowałeś kropki, a więc mamy dowolna ilość cyfr (w tym brak), potem dowolny jeden znak, potem co najmniej jedna cyfra - a899.00 pasuje jak ulał z a899 w pierwszej grupie i .00 w drugiej. Zacytuj kropkę (\) i będzie ciut lepiej (pamiętaj o eskejpowaniu samych backslashy, czyli zamiast "\." daj "\\.").
Teraz moja wersja:
[0-9] to \d
\d+\.?\d*|\.\d+ - co najmniej jedna cyfra, po której może wystąpić co najwyżej jedna kropka, po której może wystąpić dowolna ilość cyfr (dziwna to reguła, żeby liczba się kończyła kropką, ale taka część jest u Ciebie - mam na myśli [0-9]+\.[0-9]*) lub kropka, po której występuje co najmniej jedna cyfra.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.