web-dev-qa-db-fra.com

Le moyen le plus rapide de vérifier une chaîne est alphanumérique en Java

Quel est le moyen le plus rapide de vérifier qu'une chaîne ne contient que des caractères alphanumériques.

J'ai du code qui va mâcher beaucoup de CPU et je me demande s'il y aura un moyen plus rapide que d'utiliser des expressions régulières précompilées.

MISE À JOUR: Tant de votes négatifs, voulez-vous expliquer? Stackoverflow ne doit pas être utilisé pour discuter quel algorithme utiliser pour réaliser une tâche pourrait être plus rapide?

20
Jacob

J'ai écrit les tests qui comparent l'utilisation d'expressions régulières (selon les autres réponses) à la non-utilisation d'expressions régulières. Tests effectués sur une machine quad core OSX10.8 exécutant Java 1.6

Fait intéressant, l'utilisation d'expressions régulières s'avère être environ 5 à 10 fois plus lente que l'itération manuelle sur une chaîne. De plus, la fonction isAlphanumeric2() est légèrement plus rapide que isAlphanumeric(). L'un prend en charge le cas où les numéros Unicode étendus sont autorisés, et l'autre s'applique lorsque seuls les numéros standard ASCII sont autorisés.

public class QuickTest extends TestCase {

    private final int reps = 1000000;

    public void testRegexp() {
        for(int i = 0; i < reps; i++)
            ("ab4r3rgf"+i).matches("[a-zA-Z0-9]");
    }

public void testIsAlphanumeric() {
    for(int i = 0; i < reps; i++)
        isAlphanumeric("ab4r3rgf"+i);
}

public void testIsAlphanumeric2() {
    for(int i = 0; i < reps; i++)
        isAlphanumeric2("ab4r3rgf"+i);
}

    public boolean isAlphanumeric(String str) {
        for (int i=0; i<str.length(); i++) {
            char c = str.charAt(i);
            if (!Character.isDigit(c) && !Character.isLetter(c))
                return false;
        }

        return true;
    }

    public boolean isAlphanumeric2(String str) {
        for (int i=0; i<str.length(); i++) {
            char c = str.charAt(i);
            if (c < 0x30 || (c >= 0x3a && c <= 0x40) || (c > 0x5a && c <= 0x60) || c > 0x7a)
                return false;
        }
        return true;
    }

}
21
Jacob

Utilisez String.matches () , comme:

String myString = "qwerty123456";
System.out.println(myString.matches("[A-Za-z0-9]+"));

Ce n'est peut-être pas l'approche la plus rapide possible. Mais en général, il est inutile d'essayer de rivaliser avec les personnes qui écrivent la "bibliothèque standard" du langage en termes de performances.

33
aroth

Une expression régulière sera probablement assez efficace, car vous spécifierez des plages: [0-9a-zA-Z]. En supposant que le code d'implémentation des expressions rationnelles est efficace, cela nécessiterait simplement une comparaison des limites supérieure et inférieure pour chaque plage. Voici essentiellement ce qu'une expression régulière compilée devrait faire:

boolean isAlphanumeric(String str) {
    for (int i=0; i<str.length(); i++) {
        char c = str.charAt(i);
        if (c < 0x30 || (c >= 0x3a && c <= 0x40) || (c > 0x5a && c <= 0x60) || c > 0x7a)
            return false;
    }

    return true;
}

Je ne vois pas comment votre code pourrait être plus efficace que cela, car chaque caractère devra être vérifié, et les comparaisons ne pourraient pas être vraiment plus simples.

2
snibbets