Mam ciąg, który ładuję w całej aplikacji i zmienia się on z cyfr na litery i tak dalej. Mam proste if
stwierdzenie, czy zawiera litery lub cyfry, ale coś nie działa poprawnie. Oto fragment kodu.
String text = "abc";
String number;
if (text.contains("[a-zA-Z]+") == false && text.length() > 2) {
number = text;
}
Chociaż text
zmienna zawiera litery, warunek zwraca wartość jako true
. I &&
powinny ewaluować, ponieważ oba warunki muszą być spełnione true
, aby przetworzyćnumber = text;
==============================
Rozwiązanie:
Udało mi się to rozwiązać za pomocą następującego kodu podanego w komentarzu do tego pytania. Wszystkie pozostałe posty są również ważne!
To, co wykorzystałem, działało, pochodzi z pierwszego komentarza. Chociaż wszystkie podane przykładowe kody również wydają się być prawidłowe!
String text = "abc";
String number;
if (Pattern.matches("[a-zA-Z]+", text) == false && text.length() > 2) {
number = text;
}
java
string
if-statement
RedHatcc
źródło
źródło
matches("\\d{2,}")
spróbuj albo z -Pattern
iMatcher
Pattern.matches("[a-zA-Z]+", text) == false
można uprościć do!Pattern.matches("[a-zA-Z]+", text)
boolean isNumeric = someString.chars().allMatch(x -> Character.isDigit(x));
formularzaMax Malysh
Post.Odpowiedzi:
Jeśli będziesz przetwarzał numer jako tekst, zmień:
do:
Zamiast sprawdzać, czy ciąg nie zawiera znaków alfabetycznych, sprawdź, czy zawiera on tylko cyfry.
Jeśli faktycznie chcesz użyć wartości liczbowej, użyj
Integer.parseInt()
lub,Double.parseDouble()
jak wyjaśniono poniżej.Na marginesie, ogólnie uważa się za złą praktykę porównywanie wartości logicznych z
true
lubfalse
. Po prostu użyjif (condition)
lubif (!condition)
.źródło
^[0-9]+$
), W przeciwnym razieabc123def
będzie to traktowane jako liczba.matches()
zwraca wartość true tylko wtedy, gdy jest to pełne dopasowanie od początku do końca.&& (text.length() > 2)
. Wszystko można sprawdzić według wzoru regularnego:if (text.matches("[0-9]{3,}")
Możesz także użyć NumberUtil.isCreatable (String str) z Apache Commons
źródło
NumberUtil.isCreatable(String str)
aby można było użyć tego, o co prosi pierwotne pytanie. Np.NumberUtil.isCreatable( "09" )
Zwracafalse
, chociaż"09"
zawiera tylko liczby .Tak bym to zrobił:
$
Pozwala uniknąć częściowego dopasowania np;1B
.źródło
text.length() > 2
części, więc po prostu zastąpiłem^[0-9]*$
ją,^[0-9]+$
aby mieć pewność, że mam co najmniej jeden numer.Pod względem wydajności
parseInt
i takie są znacznie gorsze niż inne rozwiązania, ponieważ przynajmniej wymagają obsługi wyjątków.Przeprowadziłem testy jmh i odkryłem, że iteracja ciągów przy użyciu
charAt
i porównywanie znaków z znakami granicznymi jest najszybszym sposobem sprawdzenia, czy łańcuch zawiera tylko cyfry.Testy JMH
Testy porównują wydajność
Character.isDigit
vsPattern.matcher().matches
vsLong.parseLong
vs sprawdzanie wartości char.Te sposoby mogą dawać różne wyniki dla łańcuchów niepasujących i łańcuchów zawierających znaki +/-.
Testy działają w trybie przepustowości (im większa, tym lepiej ) z 5 iteracjami rozgrzewania i 5 iteracjami testów.
Wyniki
Należy pamiętać, że
parseLong
jest prawie 100 razy wolniej niżisDigit
na pierwszym obciążeniu testowym.Zestaw testowy
Zaktualizowano 23 lutego 2018 r
charAt
zamiast tworzyć dodatkową tablicę, a drugi używaIntStream
kodów charZaktualizowano 23 lutego 2018 r
źródło
Aby po prostu sprawdzić ciąg, który zawiera tylko ALFABETY, użyj następującego kodu:
Aby po prostu sprawdzić ciąg, który zawiera tylko NUMBER, użyj następującego kodu:
Mam nadzieję, że to komuś pomoże!
źródło
boolean isNum = text.chars (). allMatch (c -> c> = 48 && c <= 57)
źródło
boolean isNum = text.chars().allMatch(c -> c >= '0' && c <= '9')
Możesz użyć Regex.Match
Lub możesz użyć wersji podobnych
Integer.parseInt(String)
lub lepszychLong.parseLong(String)
dla większych liczb, takich jak na przykład:A następnie przetestuj za pomocą:
źródło
Poniżej wyrażeń regularnych można sprawdzić, czy ciąg ma tylko liczbę, czy nie:
if (str.matches(".*[^0-9].*")) or if (str.matches(".*\\D.*"))
Oba powyższe warunki zostaną zwrócone,
true
jeśli ciąg znaków zawiera cyfry inne niż liczby. Nafalse
ciąg ma tylko liczby.źródło
Apache Commons Lang zapewnia
org.apache.commons.lang.StringUtils.isNumeric(CharSequence cs)
, który przyjmuje jako argument aString
i sprawdza, czy składa się ze znaków czysto numerycznych (w tym liczb ze skryptów niełacińskich). Ta metoda zwraca,false
jeśli występują takie znaki, jak spacja, minus, plus oraz separatory dziesiętne, takie jak przecinek i kropka.Inne metody tej klasy pozwalają na dalsze kontrole numeryczne.
źródło
public static boolean isNumeric(String str) { if (str == null) { return false; } else { int sz = str.length(); for(int i = 0; i < sz; ++i) { if (!Character.isDigit(str.charAt(i))) { return false; } } return true; } }
Istnieje wiele możliwości uzyskiwania liczb ze
String
s w Javie (i odwrotnie). Możesz pominąć część wyrażenia regularnego, aby uniknąć komplikacji.Na przykład możesz spróbować zobaczyć, co
Double.parseDouble(String s)
za ciebie zwraca. Powinien wyrzucić a,NumberFormatException
jeśli nie znajdzie odpowiedniej wartości w ciągu. Sugerowałbym tę technikę, ponieważ faktycznie można skorzystać z wartości reprezentowanej przezString
jako typ liczbowy.źródło
Oto mój kod, mam nadzieję, że ci to pomoże!
źródło
Ten kod jest już napisany. Jeśli nie przeszkadza ci (wyjątkowo) niewielkie uderzenie wydajności - które prawdopodobnie nie jest gorsze niż dopasowanie wyrażenia regularnego - użyj Integer.parseInt () lub Double.parseDouble () . Dzięki temu od razu dowiesz się, czy String to tylko liczby (lub odpowiednio liczba). Jeśli potrzebujesz obsługiwać dłuższe ciągi liczb, zarówno konstruktory sportowe BigInteger , jak i BigDecimal, które akceptują ciągi. Każde z nich zgłosi wyjątek NumberFormatException, jeśli spróbujesz przekazać go bez liczby (całkowite lub dziesiętne, na podstawie oczywiście wybranego). Alternatywnie, w zależności od wymagań, po prostu iteruj znaki w ciągu znaków i zaznacz Character.isDigit ()i / lub Character.isLetter () .
źródło
źródło
źródło
Przykład testu roboczego
Nadal twój kod może być podzielony na „1a” itp., Więc musisz sprawdzić wyjątek
Metodą sprawdzania nie jest ciąg znaków lub nie
źródło
Złą praktyką jest angażowanie wyjątków rzucających / obsługujących w taki typowy scenariusz.
Dlatego parseInt () nie jest ładny, ale regex to eleganckie rozwiązanie tego problemu, ale dbać o następujących:
-fractions
numery -wykluczające
-decimal separator może się różnić w contries ( „”, np „” lub)
-sometimes dozwolone jest stosowanie tak zwanego separatora tysięcy, takiego jak spacja lub przecinek, np. 12 324 1000 3555
Aby obsłużyć wszystkie niezbędne przypadki w aplikacji, musisz zachować ostrożność, ale ten regex obejmuje typowe scenariusze (dodatnie / ujemne i ułamkowe, oddzielone kropką): ^ [- +]? \ D *.? \ D + $
For testowanie, polecam regexr.com .
źródło
Nieznacznie zmodyfikowana wersja Adama Bodrogiego:
Musiałem użyć tego dzisiaj, więc właśnie opublikowałem moje modyfikacje. Obejmuje notację walutową, tysiące przecinków lub okresów oraz niektóre walidacje. Nie obejmuje innych notowań walutowych (euro, cent), przecinki weryfikacyjne są co trzecią cyfrą.
źródło