Como saber se uma String pode ser um int

Se fizer uma regex que valide um pattern “[0-9]*”, como o colega indicou, e o valor for “12.5”, ele retornará que este valor NÃO É NUMÉRICO… excelente solução ein?

Se fizer assim funciona:

void testar() {
   if ("-2324.00".matches("((-|\\+)?[0-9]+(\\.[0-9]+)?)+")) {  
      System.out.println("Is a number");  
    } else {  
      System.out.println("Is not a number");  
    }  
}

E veja como fica fácil a manutenção!!! bem mais fácil do que colocar um “try… catch” né? É só bater o olho que já dá pra ver o que faz… É por isso que dizem que tá cheio de pogs os códigos por aí… tem gente que acha que complexidade é bonito e tem medo de não ser mais útil se fizer a coisa simples… o bom desenvolvedor é aquele que sabe usar a tecnologia ao seu favor e não aquele que adora reinventar a roda ou complicar tudo pra achar que é insubistituível…

“12.5” é um inteiro ?

Bom, o autor do tópico quer saber se pode ser um int que não aceita valores numéricos, mas até aí tudo bem, entendo o que você diz.

Agora roda esse código, me fala o que imprime.public static void main(String[] args){ try{ String str = "12.04"; int num = Integer.parseInt(str); System.out.println("É um número"); }catch (NumberFormatException e){ System.out.println("Não é um número"); } }

nice this

[code]public class exemploRegex{

private static final String REGEX = ":";
private static final String INPUT =
    "um:dois:tres:quatro:cinco";

public static void main(String[] args) {
    Pattern p = Pattern.compile(REGEX);
    String[] items = p.split(INPUT);
    for(String saida : items) {
        System.out.println(saida);
    }
}

}[/code]

:cry: :cry: :cry:

Muitas linguagens têm um método chamado “isNumeric” ou coisa parecida.

A coisa mais simples a fazer (e que costumo fazer) é você criar um método público estático em uma classe utilitária que receba uma string e diga “true” se é numérico.

Agora, qual é a sua definição de numérico?

Isto aqui para você é numérico “3.1415926535E+314”? Se for, use Double.parseDouble e cheque a exceção NumberFormatException (essa é a maneira mais rápida de checar - muito mais rápido que usar uma expressão regular).

Se isto for numérico (“R$ 3.141,92”? ) Nesse caso, uma expressão regular até vai bem. Senão, use DecimalFormat.parse e na hora de configurar o DecimalFormat não se esqueça de passar o DecimalFormatSymbols adequado e tratar ParseException. Cuidado que DecimalFormat.parse não é thread-safe :frowning:

Ou só isto “-12345” é numérico? Se for o caso, use Long.parseLong e cheque NumberFormatException.

Se é bonito ou não, você esconde isso dentro da implementação desse método, que você vai escrever apenas uma vez, não vai deixar exposto em 200 lugares diferentes no seu código.

Esta discussão está sobre o que é mais viável em termos de manutenção de código: Efetuar uma validação de número com regex ou com exception. Expus minhas considerações sobre isso na outra mensagem, inclusive com um exemplo bem didático… Suas considerações são que ele quer validar um “int”? Não me parece muito convincente… Afinal, para validar números em geral, e não somente ints, você prefere a regex?

[quote=digaoneves][quote=douglaskd]se eu quizer retornar true para todos que se enquadrem no tipo numeral: BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, Short

qual seria a forma mais “elegante” de fazer ?

como ficaria um método bem feito ?

todos esses tipos são classes derivadas da classe abstrata java.lang.Number, [/quote]

As soluções apresentadas são para verificar se uma String possui caracteres numéricos.

Se quer saber se um objeto é um Number, use instanceof.[/quote]

não não,

é realmente as sobre as soluções postadas

no c# uso o tryParse, se quero saber se é numero, coloco dentro de 1 método vários tryparse, se um deles é verdadeiro retorna true

mas gostei da regex que o cara postou acima…bem completa

Extamente, entanglement . A discussão deste tópico gira exatamente em torno do que você expôs. Alguns preferem complicar tudo e usar regex, e depois, pra simplificar, dizem que só vale pra ints… tem que haver uma solução geral, e neste caso, as exceptions (NumberFormatException, ParseException etc.) existem exatamente pra isso!

Esta discussão está sobre o que é mais viável em termos de manutenção de código: Efetuar uma validação de número com regex ou com exception. Expus minhas considerações sobre isso na outra mensagem, inclusive com um exemplo bem didático… Suas considerações são que ele quer validar um “int”? Não me parece muito convincente… Afinal, para validar números em geral, e não somente ints, você prefere a regex?[/quote]

Viu o que o entanglement comentou ? Isso são algumas possibilidades. Saber se uma String é numérica, há considerações a serem feitas. Minha postagem foi exclusiva ao tópico e ponto final. O tópico é bem claro quando diz “uma String em um int”. Só para esse caso, gosto de usar uma regex por ela ser extremamente simples ("\d+").

Fora isso, é necessário uma análise, pois como o entanglement citou, podemos considerar até valores monetários. Ai é outra conversa, principalmente porque encher o código de regex ou simplesmente usar um único método em uma classe útil que usa regex mas ele é muito “acionado” pode gerar uma “lentidão” considerável no sistema, já que sim, a regex é lenta.

Não acho bacana fugirmos do tópico, até porque estamos na área do “Java Básico” e o autor do tópico pode não achar a solução pretendida, e pior, atrapalharmos mais do que ajudarmos.

Mas para que usar regex, sendo que o Integer.parse do Java já faz a verificação bonitinha ?

Pra que re-inventar a roda ?

O java já tem o método implementado, basta usar.

TRY/CATCH ++

Parabéns, nel, agora sim você pareceu um analista de respeito, que faz análises melhores, porém, precisou ser provocado pra ter esta iniciativa. Que tal tentar agir assim sempre, sem precisar de um empurrãozinho? Faça que verá como melhorará em tudo. Regex podem ser simples para casos simples, porém, quando estes casos se complicam, a regex tende a se complicar por 100… então, voltando à primeira mensagem: EVITE REGEX SEMPRE QUE POSSÍVEL, USE PADRÕES.

Discussões como estas fazem falta aqui no GUJ. Precisamos de mais gente com este fervor para discutir ideias. Parabéns a todos pela ótima discussão.

Eu normalmente utilizo os commons da apache pra esse tipo de verificação, o que não vem ao caso já que estamos discutindo soluções nativas.
Mas só de curiosidade, fui dar uma olhada em como eles implementam o StringUtils.isNumeric e achei interessante a abordagem, diferente das soluções do regex e da exception:

Lembrando que realmente 10.20 não é um inteiro, então algumas das considerações anteriores não fazem sentido.
Mas -3 é um inteiro válido, que passa pelo Integer.parseInt mas não passa pela maior parte das expressões regulares postadas, nem pelo meu código abaixo.

     /**
         * <p>Checks if the String contains only unicode digits.
         * A decimal point is not a unicode digit and returns false.</p>
         *
         * <p><code>null</code> will return <code>false</code>.
         * An empty String ("") will return <code>true</code>.</p>
         *
         * <pre>
         * StringUtils.isNumeric(null)   = false
         * StringUtils.isNumeric("")     = true
         * StringUtils.isNumeric("  ")   = false
         * StringUtils.isNumeric("123")  = true
         * StringUtils.isNumeric("12 3") = false
         * StringUtils.isNumeric("ab2c") = false
         * StringUtils.isNumeric("12-3") = false
         * StringUtils.isNumeric("12.3") = false
         * </pre>
         *
         * @param str  the String to check, may be null
         * @return <code>true</code> if only contains digits, and is non-null
         */
        public static boolean isNumeric(String str) {
            if (str == null) {
                return false;
            }
            int sz = str.length();
            for (int i = 0; i < sz; i++) {
                if (Character.isDigit(str.charAt(i)) == false) {
                    return false;
                }
            }
            return true;
        }

[quote=daveiga]Eu normalmente utilizo os commons da apache pra esse tipo de verificação, o que não vem ao caso já que estamos discutindo soluções nativas.
Mas só de curiosidade, fui dar uma olhada em como eles implementam o StringUtils.isNumeric e achei interessante a abordagem, diferente das soluções do regex e da exception:

Lembrando que realmente 10.20 não é um inteiro, então algumas das considerações anteriores não fazem sentido.
Mas -3 é um inteiro válido, que passa pelo Integer.parseInt mas não passa pela maior parte das expressões regulares postadas, nem pelo meu código abaixo.

[code]
/**
*

Checks if the String contains only unicode digits.
* A decimal point is not a unicode digit and returns false.


*
*

null will return false.
* An empty String ("") will return true.


*
*

* StringUtils.isNumeric(null) = false
* StringUtils.isNumeric("") = true
* StringUtils.isNumeric(" ") = false
* StringUtils.isNumeric(“123”) = true
* StringUtils.isNumeric(“12 3”) = false
* StringUtils.isNumeric(“ab2c”) = false
* StringUtils.isNumeric(“12-3”) = false
* StringUtils.isNumeric(“12.3”) = false
*

*
* @param str the String to check, may be null
* @return true if only contains digits, and is non-null
*/
public static boolean isNumeric(String str) {
if (str == null) {
return false;
}
int sz = str.length();
for (int i = 0; i < sz; i++) {
if (Character.isDigit(str.charAt(i)) == false) {
return false;
}
}
return true;
}

[/code][/quote]

Agora me diz…o que você acha tem implementado dentro do “isDigit()” ?

public static boolean isDigit(int paramInt) { boolean bool = false; if ((paramInt >= 0) && (paramInt <= 255)) { bool = CharacterDataLatin1.isDigit(paramInt); } else { int i = getPlane(paramInt); switch (i) { case 0: bool = CharacterData00.isDigit(paramInt); break; case 1: bool = CharacterData01.isDigit(paramInt); break; case 2: bool = CharacterData02.isDigit(paramInt); break; case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: bool = CharacterDataUndefined.isDigit(paramInt); break; case 14: bool = CharacterData0E.isDigit(paramInt); break; case 15: case 16: bool = CharacterDataPrivateUse.isDigit(paramInt); } } return bool; }

Ou seja, coisas inesperadas como 三(três em chinês), ㊃ (o dígito 4 em chinês dentro de uma bolinha), ٣ (o dígito 3 em árabe) também contam como dígitos para Character.isDigit :slight_smile:

Só complementando, e voltando ao uso da regex, não defendendo o uso da regex, mas se for usar por favor:

String a = ... ;
a.matches("^[0-9]+$");

Assim, não vai ser considerado apenas o final da string, e sim ela toda…

só eu ou todo mundo achou regex e try/catch melhor que a implementação do isnumeric que usa a isdigit ??