2008-12-16 20 views
19

chciałbym użyć wyrażenia regularnego z Java.Regex znaleźć liczbę całkowitą w ciąg

Co chcę zrobić, to znaleźć pierwszą całkowitą w ciąg.

Przykład:

String = "the 14 dogs ate 12 bones" 

Wrócimy 14.

String = "djakld;asjl14ajdka;sdj" 

Czy też powrócić 14.

To, co mam tak daleko.

Pattern intsOnly = Pattern.compile("\\d*"); 
Matcher makeMatch = intsOnly.matcher("dadsad14 dssaf jfdkasl;fj"); 
makeMatch.find(); 
String inputInt = makeMatch.group(); 
System.out.println(inputInt); 

Co robię źle?

Odpowiedz

48

Prosisz do 0 lub więcej cyfr. Trzeba poprosić o 1 lub więcej:

"\\d+" 
0

Herezje poręczne jeden zrobiłem dla C# z leków generycznych. będzie pasować w oparciu o wyrażenie regularne i powrócić typy musisz:

public T[] GetMatches<T>(string Input, string MatchPattern) where T : IConvertible 
    { 
     List<T> MatchedValues = new List<T>(); 
     Regex MatchInt = new Regex(MatchPattern); 

     MatchCollection Matches = MatchInt.Matches(Input); 
     foreach (Match m in Matches) 
      MatchedValues.Add((T)Convert.ChangeType(m.Value, typeof(T))); 

     return MatchedValues.ToArray<T>(); 
    } 

wtedy, jeśli chciał chwycić tylko numery i zwrócić je w ciąg [] tablica:

string Test = "22$data44abc"; 
string[] Matches = this.GetMatches<string>(Test, "\\d+"); 

Mam nadzieję, że ten jest użyteczne dla kogoś ...

3

Wygląda na to, że inne rozwiązania nie poradziły sobie z +/- i takimi przypadkami jak 2e3, które obsługuje java.lang.Integer.parseInt(String), więc podejmę decyzję. Jestem nieco niedoświadczony w regex, więc może być wykonane kilka błędów, używane coś regex parser Java nie obsługuje lub stało się zbyt skomplikowane, ale wypowiedzi wydawało się do pracy w Kiki 0.5.6.

Wszystkie wyrażenia regularne są dostarczane zarówno w formacie bez zmiany znaczenia do czytania, jak iw formacie zumieszczonym, którego można używać jako ciągu literowego w języku Java.

Aby uzyskać byte, short, int lub długo z ciągiem:

unescaped: ([\+-]?\d+)([eE][\+-]?\d+)? 
    escaped: ([\\+-]?\\d+)([eE][\\+-]?\\d+)? 

... i dla punktów bonusowych ...

Aby uzyskać podwójne lub pływaka z ciągiem:

unescaped: ([\+-]?\d(\.\d*)?|\.\d+)([eE][\+-]?(\d(\.\d*)?|\.\d+))? 
    escaped: ([\\+-]?\\d(\\.\\d*)?|\\.\d+)([eE][\\+-]?(\\d(\\.\\d*)?|\\.\\d+))? 
+0

To nadal przechwytuje liczby takie jak 099, na których java parseInt rzuci NumberFormatException. –

+0

Muszę cię źle zrozumieć. '099' jest konwertowane na 99 przez' Integer.parseInt() ', patrz: http://pastie.org/1881188 – bgw

+0

Czy to nadal działa, gdy liczba jest w ciągu znaków typu" 2-1 "? Poprawnie odnalazłby pierwszy mecz "2", ale drugi mecz "-1" jest niepoprawny, ponieważ tam jest - jest operatorem. Musiałbyś użyć czegoś nawet bardziej wyszukanego (ang. Lookbehind, który zignorowałby a + lub - jeśli bezpośrednio poprzedzająca rzecz jest również liczbą). – AJMansfield

0

Oprócz tego, co PiPeep powiedział, jeśli starają się dopasować całkowitymi w wyrażeniu, tak że 1 + 2 - 3 będzie tylko dopasować 1, 2 i 3, zamiast 1, + 2 i - 3, to faktycznie trzeba użyć oświadczenie lookbehind, a część chcesz faktycznie będą zwracane przez Matcher.group(2) aniżeli właśnie Matcher.group() ,

unescaped: ([0-9])?((?(1)(?:[\+-]?\d+)|)(?:[eE][\+-]?\d+)?) 
    escaped: ([0-9])?((?(1)(?:[\\+-]?\\d+)|)(?:[eE][\\+-]?\\d+)?) 

również na takie rzeczy jak someNumber - 3, gdzie someNumber jest nazwa zmiennej lub coś w tym stylu, można użyć

unescaped: (\w)?((?(1)(?:[\+-]?\d+)|)(?:[eE][\+-]?\d+)?) 
    escaped: (\\w)?((?(1)(?:[\\+-]?\\d+)|)(?:[eE][\\+-]?\\d+)?) 

choć oczywiście, że nie będzie działać, jeśli parsowania ciąg jak The net change to blahblah was +4

+0

Nie widzę żadnych wyrażeń w tych wyrażeń regularnych. To, co widzę, to [usługi warunkowe] (http://www.regular-expressions.info/conditional.html), które nie są obsługiwane w Javie. –

+0

Ohhhh ... to dlatego mój program nie działa ... – AJMansfield

0

Specyfikacja java faktycznie daje temu potworowi wyrażenie regularne do analizowania podwajań. Jednak jest to uważane za złą praktykę, po prostu próbując parsować z zamierzonym typem i łapiąc błąd, wydaje się być nieco bardziej czytelne.

DOUBLE_PATTERN = Pattern 
     .compile("[\\x00-\\x20]*[+-]?(NaN|Infinity|((((\\p{Digit}+)(\\.)?((\\p{Digit}+)?)" 
       + "([eE][+-]?(\\p{Digit}+))?)|(\\.((\\p{Digit}+))([eE][+-]?(\\p{Digit}+))?)|" 
       + "(((0[xX](\\p{XDigit}+)(\\.)?)|(0[xX](\\p{XDigit}+)?(\\.)(\\p{XDigit}+)))" 
       + "[pP][+-]?(\\p{Digit}+)))[fFdD]?))[\\x00-\\x20]*"); 
Powiązane problemy