web-dev-qa-db-fra.com

Vérifier si String est hexadécimal

J'ai une chaîne comme "09a" et j'ai besoin d'une méthode pour confirmer si le texte est hexadécimal. Le code que j'ai posté fait quelque chose de similaire, il vérifie qu'une chaîne est un nombre décimal. Je veux faire la même chose, mais pour hexadécimal.

    private static boolean isNumeric(String cadena) {
    try {
        Long.parseLong(cadena);
        return true;
    } catch (NumberFormatException nfe) {
        JOptionPane.showMessageDialog(null,"Uno de los números, excede su capacidad.");
        return false;
    }
}
13
Axel Vazquez

Il y a un Long.parseLong surchargé qui accepte un deuxième paramètre, spécifiant la base:

Long.parseLong(cadena,16);

Au lieu de cela, vous pouvez parcourir les caractères de la chaîne et appeler Character.digit(c,16) sur eux (si l’un d’eux renvoie -1, ce n’est pas un chiffre hexadécimal valide). Ceci est particulièrement utile si la chaîne est trop grande pour tenir dans une long (comme indiqué dans les commentaires, cela provoquerait une exception si la première méthode était utilisée). Exemple:

private static boolean isNumeric(String cadena) {
    if ( cadena.length() == 0 || 
         (cadena.charAt(0) != '-' && Character.digit(cadena.charAt(0), 16) == -1))
        return false;
    if ( cadena.length() == 1 && cadena.charAt(0) == '-' )
        return false;

    for ( int i = 1 ; i < cadena.length() ; i++ )
        if ( Character.digit(cadena.charAt(i), 16) == -1 )
            return false;
    return true;
}

BTW, je suggérerais de séparer les préoccupations de "tester un nombre valide" et "afficher un message à l'utilisateur", c'est pourquoi j'ai simplement retourné false dans l'exemple ci-dessus au lieu d'avertir l'utilisateur en premier.

Enfin, vous pourriez simplement utiliser une expression régulière:

cadena.matches("-?[0-9a-fA-F]+");
18
mgibsonbr

Abus horrible des exceptions. Ne fais jamais ça! (Ce n'est pas moi, c'est Effective Java de Josh Bloch). Quoi qu'il en soit, je suggère

boolean isNumeric = str.matches("\\p{XDigit}+");
16
Evgeniy Dorofeev

Utilisé cela dans mon propre code pour vérifier si la chaîne est une adresse MAC

boolean isHex = mac_addr.matches("^[0-9a-fA-F]+$");

Mon bœuf avec les autres réponses fournies dans ce fil de discussion est que si la longueur de String est grande, elle jetterait également une exception. Par conséquent, ce n'est pas très utile si vous testez si une adresse MAC est constituée d’hexadécimaux valides.

Ne soyez pas terrifié par l'utilisation de regex!

13
laycat

Long.parseLong a une seconde forme qui prend une base comme second argument.

private static boolean isHexNumber (String cadena) {
  try {
    Long.parseLong(cadena, 16);
    return true;
  }
  catch (NumberFormatException ex) {
    // Error handling code...
    return false;
  }
}
9
Tony

Voici du code pour différentes options et résultats d’exécution (JDK 8):

execution time isHex1: 4540
execution time isHex2: 420
execution time isHex3: 7907
execution time regex: 46827

Code de test:

@Test
public void testPerformance() {
    int count = 100000000;
    char[] chars = {
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
    };
    String regexString = new String(chars);
    Pattern pattern = Pattern.compile("^[0-9a-fA-F]+$");
    long start = System.currentTimeMillis();
    for (int i = 0; i < count; i++) {
        for (char c: chars) {
            isHex1(c);
        }
    }
    System.out.println("execution time isHex1: " + (System.currentTimeMillis() - start));
    start = System.currentTimeMillis();
    for (int i = 0; i < count; i++) {
        for (char c: chars) {
            isHex2(c);
        }
    }
    System.out.println("execution time isHex2: " + (System.currentTimeMillis() - start));
    for (int i = 0; i < count; i++) {
        for (char c: chars) {
            isHex3(c);
        }
    }
    System.out.println("execution time isHex3: " + (System.currentTimeMillis() - start));
    for (int i = 0; i < count; i++) {
        Matcher matcher = pattern.matcher(regexString);
        matcher.matches();
    }
    System.out.println("execution time regex: " + (System.currentTimeMillis() - start));
}

private boolean isHex1(char c) {
    return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}

private boolean isHex2(char c) {
    switch (c) {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
        case 'a':
        case 'b':
        case 'c':
        case 'd':
        case 'e':
        case 'f':
        case 'A':
        case 'B':
        case 'C':
        case 'D':
        case 'E':
        case 'F':
            return true;
        default:
            return false;
    }
}

private boolean isHex3(char c) {
    return (Character.digit(c, 16) != -1);
}
4
toongeorges

Approche sans bibliothèque

public static boolean isHexadecimal(String value)
{
    if (value.startsWith("-"))
    {
        value = value.substring(1);
    }

    value = value.toLowerCase();

    if (value.length() <= 2 || !value.startsWith("0x"))
    {
        return false;
    }

    for (int i = 2; i < value.length(); i++)
    {
        char c = value.charAt(i);

        if (!(c >= '0' && c <= '9' || c >= 'a' && c <= 'f'))
        {
            return false;
        }
    }

    return true;
}
1
Braden Steffaniak

Vous pouvez vérifier pratiquement n'importe quel texte avec la méthode ci-dessous.

public static boolean isHexadecimal(String text) {
    Objects.requireNonNull(text);
    if(text.length() < 1)
        throw new IllegalArgumentException("Text cannot be empty.");

    char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F' };

    for (char symbol : text.toCharArray()) {
        boolean found = false;
        for (char hexDigit : hexDigits) {
            if (symbol == hexDigit) {
                found = true;
                break;
            }
        }
        if(!found)
            return false;
    }
    return true;
}
0
Warrior