Melhor jeito de saber que uma String só tem Números

Ola Gente,
Por favor, preciso de ajuda!
Fui procurar na internet e fiz isso aqui :

 String choosedPort = JOptionPane.showInputDialog(null,"Insert Port Address :");
        if(choosedPort.contains("^[a-Z]") || (choosedPort.isEmpty()) ){
           JOptionPane.showMessageDialog(null,"Invalid Port Adress!");
        }  

Tenho mais uma dúvida…E se o usuário digitar “*”
ou : " _ "
ou
“+ ou &¨¨$!¨@!@&(!_$&@&¨$ ?:>><|"/–…”

Acho que deu pra entender :smiley:
Como posso fazer isso ?

1 curtida

Como sou Idiota.
Em vez de procurar se tem caracteres especiais… Eu deveria procurar se tem apenas numeros…

Procure por Regex, resolvera o seu problema

Como eu mudo esse


.contains

Pra ele ver se tem apenas numeros , seria assim :

("^[0-9]*$")

???

Valeu!
Só que ele só aceita 1 numero…
e uma Porta pode ir até 65000

E agora?

String choosedPort = JOptionPane.showInputDialog(null,"Insert Port Address :");
        if(choosedPort.matches("[0-9]"))
        {
          setJTextFieldServerPortText(choosedPort);
           
        } else
        {
             JOptionPane.showMessageDialog(null,"Invalid Port Adress!");
        }

Talvez eu esteja falando besteira, já que sou iniciante, mas já tentou usar a função isDigit?

Que tal assim:

        String portaRecebidaPeloJOptionPane = "3306";
        
        try {
            Integer porta = new Integer(portaRecebidaPeloJOptionPane);
            if (porta <= 0 || porta > 65000) {
                throw new Exception("porta inválida");
            } else {
                /* tratamento para porta válida:
                 * setJTextFieldServerPortText(choosedPort); */
            }
        } catch (Exception exception) {
            /* tratamento para porta inválida:
             * JOptionPane.showMessageDialog(null,"Invalid Port Adress!"); */
            System.out.println("porta inválida");
        }

Té mais.

http://www.mosampaio.com.br/2011/02/criar-input-text-que-so-aceita.html?m=1

No client se preocupe so com o input ser numerico como no exemplo do link, e no server voce cria validacao para o negocio, como a questao de nao deixar gravar o que for maior que 65000.

static boolean isPortaValida(String porta) {

    if (porta == null || ! porta.matches("^[0-9]{1,5}$"))
        return false;

    int portNum = Integer.parseInt(porta);

    return (portNum >= 1 && portNum <= 65535);
}

Talvez isto ajude:

[code]String numero = "65001";

    Pattern p = Pattern.compile(&quot;[0-9]{1,5}&quot;);
    Matcher m = p.matcher(String.valueOf(numero));

    if (m.matches() && Integer.parseInt(numero) &lt;= 65000) {
        System.out.println(&quot;Numero válido!&quot;);
    }[/code]

Tem gente que gosta de complicar:

try { int porta = Integer.parseInt(numero); if (porta &lt; 0 || porta &gt; 65000) { System.out.println(&quot;Porta inválida!&quot;); } else { //Porta válida! :D \o/ } } catch (NumberFormatException e) { System.out.println(&quot;Não é um número!&quot;); }

É similar a solução do M@C, mas evita criar um objeto Integer à toa, sendo que basta usar o tipo primitivo int.

[quote=ViniGodoy]Tem gente que gosta de complicar:

try { int porta = Integer.parseInt(numero); if (porta &lt; 0 || porta &gt; 65000) { System.out.println(&quot;Porta inválida!&quot;); } else { //Porta válida! :D \o/ } } catch (NumberFormatException e) { System.out.println(&quot;Não é um número!&quot;); }[/quote]

Meu problema com isso é que não gosto de usar exceções para validar regras de negócio simples. Acho mais eficiente checar os valores com ifs mesmo.

Não vejo muito ganho quando esse if envolve a complexidade de uma expressão regular (ok, essa REGEX é simples)…

Melhor é se o Java tivesse o tryParse, igual tem o C#.

Fiz um teste com as três soluções, regex compilado previamente, na hora e com exceções. Nenhuma apresenta ganhos tão significativos, ~330ns no melhor caso.

Sem regex acredito que tenha mais velocidade, segue abaixo um metodo que uso para verificar se um string contem somente numeros. Peguei de uma dica de um site ae faz tempo, e tem me ajudado sempre que precisei.

    /**
     * This method checks if a String contains only numbers
     */
    public boolean containsOnlyNumbers(String str) {
        
        //It can't contain only numbers if it's null or empty...
        if (str == null || str.length() == 0)
            return false;
        
        for (int i = 0; i < str.length(); i++) {

            //If we find a non-digit character we return false.
            if (!Character.isDigit(str.charAt(i)))
                return false;
        }
        
        return true;
    }

[quote=Bruno Laturner]Fiz um teste com as três soluções, regex compilado previamente, na hora e com exceções. Nenhuma apresenta ganhos tão significativos, ~330ns no melhor caso.

https://gist.github.com/4522146[/quote]

Quando falei em complexidade, não estava falando em performance. Só que é nem mais fácil alguém na equipe entender o catch, do que entender a Regex.
Aqui mesmo foram dadas pelo menos 3 regex diferentes.

[quote=ViniGodoy][quote=Bruno Laturner]Fiz um teste com as três soluções, regex compilado previamente, na hora e com exceções. Nenhuma apresenta ganhos tão significativos, ~330ns no melhor caso.

https://gist.github.com/4522146[/quote]

Quando falei em complexidade, não estava falando em performance. Só que é nem mais fácil alguém na equipe entender o catch, do que entender a Regex.
Aqui mesmo foram dadas pelo menos 3 regex diferentes.[/quote]
Não entendi o que estão questionando, regex vs sem regex?

Se é melhor deixar uma regex lá ou se é melhor deixar o controle de erro através de uma exceção.

O regex tem a implicação de ser mais difícil para quem lê entender. Muitos também desconfiam da performance da Regex.
E o controle de erro através de uma exceção é algo que muitos programadores evitam, ou por acharem que também gera um código confuso, ou porque vieram do C++, onde exceções são lentas de serem disparadas e capturadas.

No fundo, é uma discussão extremamente purista. Eu só comentei que o pessoal estava complicando porque a solução tratando a exceção do parseInt me pareceu óbvia demais, e não consegui entender como ainda não havia sido proposta.

[quote=M@C]Que tal assim:

        String portaRecebidaPeloJOptionPane = "3306";
        
        try {
            Integer porta = new Integer(portaRecebidaPeloJOptionPane);
            if (porta <= 0 || porta > 65000) {
                throw new Exception("porta inválida");
            } else {
                /* tratamento para porta válida:
                 * setJTextFieldServerPortText(choosedPort); */
            }
        } catch (Exception exception) {
            /* tratamento para porta inválida:
             * JOptionPane.showMessageDialog(null,"Invalid Port Adress!"); */
            System.out.println("porta inválida");
        }

Té mais.[/quote]

Muito Obrigado pelas respostas pessoal.
Eu fiz desse jeito, parecido com o que está acima.

Muito Obrigado.

Só, uma dúvida…
Essa questão de o usuário selecionar a porta pra se conectar ao chat… Ela entra como MODEL ou CONTROL?
Pra mim entraria como CONTROL…

[quote=Andre Lopes]Muito Obrigado pelas respostas pessoal.
Eu fiz desse jeito, parecido com o que está acima.[/quote]

Essa solução cria um objeto da classe Integer de maneira completamente desnecessária. A solução que postei tem um código equivalente (idêntico, na verdade), mas usando Integer.parseInt, que é o adequado caso você só precise do tipo primitivo.

[quote=Andre Lopes]Essa questão de o usuário selecionar a porta pra se conectar ao chat… Ela entra como MODEL ou CONTROL?
Pra mim entraria como CONTROL…[/quote]

O usuário seleciona na View. O controle valida se a porta está correta. E encaminha o valor da porta à classe de Sockets que está no model.