Java String-посмотрите, содержит ли строка только числа, а не буквы
у меня есть строка, которую я загружаю во всем своем приложении, и она меняется с чисел на буквы и тому подобное. У меня простой if
оператор, чтобы увидеть, содержит ли он буквы или цифры, но что-то не совсем работает правильно. Вот фрагмент.
String text = "abc";
String number;
if (text.contains("[a-zA-Z]+") == false && text.length() > 2) {
number = text;
}
хотя text
переменная содержит буквы, состояние как true
. И &&
должны eval как оба условия должны быть true
для того чтобы обрабатывать number = text;
==============================
устранение:
я смог решить эту проблему, используя следующий код, предоставленный комментарием к этому вопросу. Все остальные сообщения также действительны!
то, что я использовал, что сработало, пришло из первого комментария. Хотя все приведенные примеры кодов, по-видимому, также действительны!
String text = "abc";
String number;
if (Pattern.matches("[a-zA-Z]+", text) == false && text.length() > 2) {
number = text;
}
16 ответов
если вы будете обрабатывать числа как текст, а затем изменить:
if (text.contains("[a-zA-Z]+") == false && text.length() > 2){
в:
if (text.matches("[0-9]+") && text.length() > 2) {
вместо того, чтобы проверить, что строка не содержат алфавитные символы, убедитесь, что он содержит только числа.
если вы действительно хотите использовать числовое значение, используйте Integer.parseInt()
или Double.parseDouble()
как уже объяснили ниже.
в качестве примечания, обычно считается плохой практикой сравнивать логические значения в true
или false
. Просто используйте if (condition)
или if (!condition)
.
вы также можете использовать NumberUtil.isCreatable (String str) из Apache Commons
вот как я бы это сделал:
if(text.matches("^[0-9]*$") && text.length() > 2){
//...
}
на $
позволит избежать частичного совпадения e.g;1B
.
производительность-мудрый parseInt
и они намного хуже, чем другие решения, потому что, по крайней мере, требуют обработки исключений.
Я запустил тесты jmh и обнаружил, что итерация по строке с помощью charAt
и сравнение символов с граничными символами-самый быстрый способ проверить, содержит ли строка только цифры.
тестирование JMH
тесты сравнения производительности Character.isDigit
vs Pattern.matcher().matches
vs Long.parseLong
vs проверка значений char.
эти пути могут создайте другой результат для строк без ascii и строк, содержащих знаки+/ -.
тесты выполняются в режиме пропускной способности (больше лучше) С 5 итерациями разминки и 5 итерациями теста.
результаты
отметим, что parseLong
почти в 100 раз медленнее, чем isDigit
для первого теста.
## Test load with 25% valid strings (75% strings contain non-digit symbols)
Benchmark Mode Cnt Score Error Units
testIsDigit thrpt 5 9.275 ± 2.348 ops/s
testPattern thrpt 5 2.135 ± 0.697 ops/s
testParseLong thrpt 5 0.166 ± 0.021 ops/s
## Test load with 50% valid strings (50% strings contain non-digit symbols)
Benchmark Mode Cnt Score Error Units
testCharBetween thrpt 5 16.773 ± 0.401 ops/s
testCharAtIsDigit thrpt 5 8.917 ± 0.767 ops/s
testCharArrayIsDigit thrpt 5 6.553 ± 0.425 ops/s
testPattern thrpt 5 1.287 ± 0.057 ops/s
testIntStreamCodes thrpt 5 0.966 ± 0.051 ops/s
testParseLong thrpt 5 0.174 ± 0.013 ops/s
testParseInt thrpt 5 0.078 ± 0.001 ops/s
тесты
@State(Scope.Benchmark)
public class StringIsNumberBenchmark {
private static final long CYCLES = 1_000_000L;
private static final String[] STRINGS = {"12345678901","98765432177","58745896328","35741596328", "123456789a1", "1a345678901", "1234567890 "};
private static final Pattern PATTERN = Pattern.compile("\d+");
@Benchmark
public void testPattern() {
for (int i = 0; i < CYCLES; i++) {
for (String s : STRINGS) {
boolean b = false;
b = PATTERN.matcher(s).matches();
}
}
}
@Benchmark
public void testParseLong() {
for (int i = 0; i < CYCLES; i++) {
for (String s : STRINGS) {
boolean b = false;
try {
Long.parseLong(s);
b = true;
} catch (NumberFormatException e) {
// no-op
}
}
}
}
@Benchmark
public void testCharArrayIsDigit() {
for (int i = 0; i < CYCLES; i++) {
for (String s : STRINGS) {
boolean b = false;
for (char c : s.toCharArray()) {
b = Character.isDigit(c);
if (!b) {
break;
}
}
}
}
}
@Benchmark
public void testCharAtIsDigit() {
for (int i = 0; i < CYCLES; i++) {
for (String s : STRINGS) {
boolean b = false;
for (int j = 0; j < s.length(); j++) {
b = Character.isDigit(s.charAt(j));
if (!b) {
break;
}
}
}
}
}
@Benchmark
public void testIntStreamCodes() {
for (int i = 0; i < CYCLES; i++) {
for (String s : STRINGS) {
boolean b = false;
b = s.chars().allMatch(c -> c > 47 && c < 58);
}
}
}
@Benchmark
public void testCharBetween() {
for (int i = 0; i < CYCLES; i++) {
for (String s : STRINGS) {
boolean b = false;
for (int j = 0; j < s.length(); j++) {
char charr = s.charAt(j);
b = '0' <= charr && charr <= '9';
if (!b) {
break;
}
}
}
}
}
}
Обновлено 23 февраля 2018
- добавить еще два случая - один с использованием
charAt
вместо создания дополнительного массива и другого с помощьюIntStream
Чара коды - добавить немедленный перерыв, если не цифра найдена для зацикленных тестовых случаев
- возвращает false для пустой строки для зацикленных тестовых случаев
Обновлено 23 февраля 2018
- добавить еще один тест (самый быстрый!), который сравнивает значение char без использования stream
есть много возможностей для получения номера от String
s в Java (и наоборот). Возможно, вы захотите пропустить часть regex, чтобы избавить себя от этого усложнения.
например, вы можете попробовать и посмотреть, что Double.parseDouble(String s)
возвращает для вас. Он должен бросить NumberFormatException
если он не находит соответствующего значения в строке. Я бы предложил этот метод, потому что вы могли бы использовать значение, представленное String
Как числовой тип.
вы можете использовать регулярное выражение.Матч
if(text.matches("\d*")&& text.length() > 2){
System.out.println("number");
}
или вы можете использовать onversions как Integer.parseInt(String)
или лучше Long.parseLong(String)
для больших чисел
например:
private boolean onlyContainsNumbers(String text) {
try {
Long.parseLong(text);
return true;
} catch (NumberFormatException ex) {
return false;
}
}
а затем проверить с:
if (onlyContainsNumbers(text) && text.length() > 2) {
// do Stuff
}
Apache Commons Lang предоставляет org.apache.commons.lang.StringUtils.isNumeric(CharSequence cs)
, который принимает в качестве аргумента a String
и проверяет, состоит ли он из чисто числовых символов (включая числа из нелатинских скриптов). Этот метод возвращает false
Если есть символы, такие как пробел, минус, плюс и десятичные разделители, такие как запятая и точка.
другие методы этого класса допускают дальнейшие числовые проверки.
чтобы просто проверить строку, которая содержит только алфавиты, используйте следующий код:
if (text.matches("[a-zA-Z]+"){
// your operations
}
чтобы просто проверить строку, которая содержит только номер, используйте следующий код:
if (text.matches("[0-9]+"){
// your operations
}
надеюсь, это поможет кому-то!
этот код уже написан. Если вы не против (очень) малой производительности-это, вероятно, не хуже, чем regex матча-используйте целое число.parseInt() или двойной.parseDouble(). Это сразу скажет вам, Является ли строка только числами (или это номер, в зависимости от обстоятельств). Если вам нужно обрабатывать более длинные строки чисел, оба BigInteger и BigDecimal спорт конструкторы, которые принимают строки. Любой из эти бросят NumberFormatException Если вы попытаетесь передать ему не-число (интегральное или десятичное, на основе выбранного вами, конечно). Поочередно, в зависимости от ваших требований, просто повторите символы в строке и проверьте символ.isDigit() и/или
import java.util.*;
class Class1 {
public static void main(String[] argh) {
boolean ans = CheckNumbers("123");
if (ans == true) {
System.out.println("String contains numbers only");
} else {
System.out.println("String contains other values as well");
}
}
public static boolean CheckNumbers(String input) {
for (int ctr = 0; ctr < input.length(); ctr++) {
if ("1234567890".contains(Character.valueOf(input.charAt(ctr)).toString())) {
continue;
} else {
return false;
}
}
return true;
}
}
ниже regexs можно использовать, чтобы проверить, имеет ли строка только номер или нет:
if (str.matches(".*[^0-9].*")) or if (str.matches(".*\D.*"))
оба условия выше вернутся true
если строка содержит не цифры. On false
, строка содержит только цифры.
Character first_letter_or_number = query.charAt(0);
//------------------------------------------------------------------------------
if (Character.isDigit())
{
}
else if (Character.isLetter())
{
}
рабочий тестовый пример
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
public class PaserNo {
public static void main(String args[]) {
String text = "gg";
if (!StringUtils.isBlank(text)) {
if (stringContainsNumber(text)) {
int no=Integer.parseInt(text.trim());
System.out.println("inside"+no);
} else {
System.out.println("Outside");
}
}
System.out.println("Done");
}
public static boolean stringContainsNumber(String s) {
Pattern p = Pattern.compile("[0-9]");
Matcher m = p.matcher(s);
return m.find();
}
}
все еще ваш код может быть сломан "1a" и т. д., Поэтому вам нужно проверить исключение
if (!StringUtils.isBlank(studentNbr)) {
try{
if (isStringContainsNumber(studentNbr)){
_account.setStudentNbr(Integer.parseInt(studentNbr.trim()));
}
}catch(Exception e){
e.printStackTrace();
logger.info("Exception during parse studentNbr"+e.getMessage());
}
}
метод проверки нет-строка или нет
private boolean isStringContainsNumber(String s) {
Pattern p = Pattern.compile("[0-9]");
Matcher m = p.matcher(s);
return m.find();
}
Это плохая практика, чтобы включить любое исключение бросая / обработки в такой типичный сценарий.
поэтому parseInt () не очень хорош, но регулярное выражение является элегантным решением для этого, но позаботьтесь о следующем:
- дроби
-отрицательные числа
- десятичный разделитель может отличаться в Контри (например,', ' или '.')
- иногда разрешается иметь так называемый тысячный разделитель, например пробел или запятую, например 12,324,1000.355
To обрабатывать все необходимые случаи в вашем приложении вы должны быть осторожны, но это регулярное выражение охватывает типичные сценарии (положительные/отрицательные и дробные, разделенные точкой): ^[-+]?\д.*?\д$+
для тестирования я рекомендую regexr.com.
вот мой код, надеюсь это поможет вам !
public boolean isDigitOnly(String text){
boolean isDigit = false;
if (text.matches("[0-9]+") && text.length() > 2) {
isDigit = true;
}else {
isDigit = false;
}
return isDigit;
}