Regex - jak wyciągnać z tekstu tylko Integery?

0

Potrzebuję odczytać z pliku txt tylko zmienne typu Integer.
Załóżmy, że plik wygląda tak:
1 3 4 - 23 -34 0.32 34d 100.0 +18

Regex powinien odczytać 1, 3, 4 (- 23 nie, bo jest spacja pomiędzy), -34, +18.

Trochę kobinowałem sam, ale napotkałem np na problemy typu:

  • jak chciałem uwzględnić dowolną ilość whitespace'ów to nie wczytywało liczb obok siebie
  • jak juz wczytywało, to nie uwzględniało np. 1(początek linii) itp.

Chodzi o to, żeby odczytać tylko i wyłącznie liczby typu Integer uwzględniając dodanie i ujemne, całą reszte olewamy.

Nie musi być to regex oczywiście, jeżeli ktoś ma inny pomysł chętnie spróbuję.

0

Ominięcie tego - 23 uważam za dość trudne bo i czemu miałyś nie wczytać 23? o_O A tak poza tym
([\-+]?\d+)\s*

0

Bardziej miałem na myśli, żeby nie zrobić z - 23 => -23. Kiedyś się spotkałem w jakimś zadaniu z tym i było wielkie zdziwienie :)

Zaraz sprawdzę, dzieki za szybką odp.

@Edit

http://regexr.com/3ani2

Łapie 0, 32 i takie tam. Program ma po prostu olać wszystko co nie jest gołą i wesołą liczbą.

0
Fi3rce napisał(a):

1 3 4 - 23 -34 0.32 34d 100.0 +18

Regex powinien odczytać 1, 3, 4 (- 23 nie, bo jest spacja pomiędzy), -34, +18.

może najpierw spróbuj sprecyzować słownie o co Ci chodzi bo widzę tu pewną nieścisłość

czemu liczba "23" ma być pominięta bo przed nią jest minus? Czy są jeszcze jakieś znaki które dyskwalifikują znalezione liczby?

0

Przepraszam, trochę zamieszałem. Chodziło mi o to, żeby z - 23 nie zrobić -23, tylko samo 23, napisałem o tym bo raz sie spotkałem z takim tokiem rozumowania oO. W dwóch słowach założenie zadania jest taki, że z txt

mam otrzymać GOŁE LICZBY TYPU INT, jeżeli przed jakaś stoi + lub - to również powinny być zaliczone.

Jeżeli jest liczba typu float to nie wyodrębniamy sobie całości tylko olewamy, tak samo jak jest np. 34d, albo 100.0 itd.

0

lepiej podaj większą ilośc danych i okresl co ma byc łapane a co nie.

Na razie najlepsze co wymyśliłem na podstawie tego co dałeś wygląda tak:
(?<!\.|-\s)(?:\+|-)?\b\d+\b(?!\.)

0
MarekR22 napisał(a):

lepiej podaj większą ilośc danych i okresl co ma byc łapane a co nie.

Nie wiem jak to mam inaczej powiedzieć. Mają być łapane 3 typu liczb:

  • 11 - nie zadne 11.0 11.342 11d itd. bez żadnego wyodrębniania, czyli jak jest 11.2 to program nie bierze 11 i idzie dalej tylko wgl. to olewa.
    Z lewej strony ma być min. 1 whitespace (chyba ze jest to poczatek linii) z prawej to samo. Nie można założyć, że część dziesiętna jest oddzielona . lub , równie dobrze może to być / ? czy cokolwiek innego.
  • +11 - akceptowalny jest znak plus z lewej strony
  • -11 - tak samo jak wyżej. Tutaj trzeba pamiętać, że musi być whitespace później minus później liczba i znowu min. 1 whitespace, bo inaczej łapie np. 12**-33**
1

A ja nadal uważam że wystarczy w takim razie
(^|\s+)([\-+]?\d+)(\s+|$)
Czyli każda liczba, ewentualnie poprzedzona + lub -, taka że jest na początku linii lub przed nią stoi biały znak i jednocześnie za nią stoi biały znak lub jest ostatnią liczbą.

0

@Shalom

No i ekstra! Tylko czemu nie reflektuje "3"?? Wszystko co wstawie między 1 a 6 jest odrzucane. http://regexr.com/3anih Jakiś bug?

Podklej te liczby z 1 postu.

String s = "12";
try {
  int i = Integer.parseInt(s);
} catch (NumberFormatException nfe) {
  
}

A gdyby wczytać text rozdzielić go i sprawdzać w pętli to przeszło by? Zakładając, że tutaj bez + przed liczbą tylko powinno same - uwzględniać.

1

wystarczy wyrażenie

/ ([+-]?\d+)(?= )/

musisz tylko na początku i końcu wejścia dokleić spacje żeby nie komplikować wyrażenia

ewentualnie wyrażenie @Shalom jest prawie dobre, tylko musisz zamienić końcówkę na look-ahead żeby nie zjadało spacji do następnego przypasowania

/(^|\s+)([\-+]?\d+)(?=\s+|$)/

1

Albo skomplikować i dać
(\s+|^)([+-]?\d+)(?=(\s+|$)) ;)

@Fi3rce jak zauważył kolega wyżej, podany regexp nie działał bo były nachodzące na siebie wyrażenia. Jeśli dodasz ?= to biały znak za liczba nie będzie łapany i wtedy wyrażenia nie będą na siebie nachodzić.

edit: spóźniłem się ;]

2

a pierwsze przypasowanie jest niepotrzebnie łapane, całe wyrażenie będzie więc wyglądało tak:

/(?:^|\s)([+-]?\d+)(?=\s|$)/

0

No i dobra, u mnie działa jak to mówią :D Dzięki Panowie

0

Zamiast kombinować z białymi znakami i początkiem/końcem linii można użyć http://regexr.com/3anjl (z małym hackiem na początku, bo zarówno - jak i + są uznawane za koniec słowa.

1 użytkowników online, w tym zalogowanych: 0, gości: 1