3 votes

Comment valider une chaîne de caractères par rapport à un jeu de caractères ?

Supposons une chaîne de caractères donnée : comment puis-je la valider par rapport à un jeu de caractères prédéfini ? J'aimerais utiliser l'ASCII 65-90 (A-Z), 33 (!), 36 ($), 38 (&), 63 (?) .

Devrais-je appliquer une regex sur la chaîne complète ? Ou est-il préférable de lire la chaîne caractère par caractère, et de faire correspondre les éléments suivants Integer sur la plage prédéfinie ?

String test = "ASDQWE!&";
for (int i = 0; i < test.length; i++) {
        int num = (int) val.charAt(i);
        //TODO validate
}

1voto

Tim Biegeleisen Points 53335

Utilisez une gamme de caractères unicode correspondant à l'ASCII 65-90 :

String test = "ASDQWE!&";
if (test.matches("[\u0041-\u005A]*")) {
    System.out.println("match!");
}

Votre exemple de chaîne ne correspond pas à l'ASCII 65-90, mais ASDQWE sans la ponctuation à la fin, c'est .

Démo

1voto

Jacob G. Points 16099

J'étais curieux et j'ai décidé de le comparer avec JMH ; voici ce que j'ai trouvé :

@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Fork(3)
public class MyBenchmark {

    @Param({"ASDQWE!&"})
    private String test;

    private static final Pattern PATTERN = Pattern.compile("[A-Z!$&?]*");

    public static void main(String[] args) throws Exception {
        org.openjdk.jmh.Main.main(args);
    }

    @Benchmark
    public boolean oldMethod() {
        for (int i = 0; i < test.length(); i++) {
            int c = test.charAt(i);

            if (c >= 65 && c <= 90) {
                continue;
            }

            switch (test.charAt(i)) {
                case 33:
                case 36:
                case 38:
                case 63:
                    break;
                default:
                    return false;
            }
        }
        return true;
    }

    @Benchmark
    public boolean newMethod() {
        return PATTERN.matcher(test).matches();
    }
}

Et ses résultats :

Benchmark                (test)  Mode  Cnt   Score   Error  Units
MyBenchmark.newMethod  ASDQWE!&  avgt   30  55.848 ± 1.275  ns/op
MyBenchmark.oldMethod  ASDQWE!&  avgt   30  14.586 ± 0.034  ns/op

Même en compilant un modèle, il est clair qu'en itérant sur le fichier String sera plus rapide, mais il est définitivement plus lisible lorsqu'on utilise une expression régulière.

0voto

Neeraj Bansal Points 157

Il est préférable d'utiliser une expression rationnelle. Parce que vous pouvez valider avec les regex en O(n) de complexité mais faire correspondre les caractères un par un aura O(m*n) de complexité.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X