Probleme de regex

lamouchetsetse Messages postés 112 Date d'inscription   Statut Membre Dernière intervention   -  
mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   -
Bonjour,
je souhaite pouvoir filtrer un chaine de caractère en fonction de certains caractères mais le code que j'ai fait ne fonctionne pas:

#!/bin/bash

test1='ter'
chaine1='pole'

if [[ $chaine1 =~ [$test1]+ ]]
then
    echo 'ok'
else
    echo 'ko'
fi


ce code m'affiche "ok" car $chaine1 contient un "e" mais ne contient ni de "t" ni de "r"
Comment vérifier si ma chaine contient bien un "t" un "e" et un "r" sachant que ces caractères sont entré par un utilisateur, donc on ne les connait pas à l’avance.

Merci

1 réponse

  1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 944
     
    Bonjour,

    Ce code m'affiche "ok" car
    $chaine1
    contient un "e" mais ne contient ni de "t" ni de "r"

    Plus exactement, ce code affiche "ok" car
    $chaine1
    contient une sous chaîne constitué d'au moins une lettre parmi t, e, r (en l'occurrence la sous-chaîne "e").

    Comment vérifier si ma chaine contient bien un "t" un "e" et un "r" sachant que ces caractères sont entré par un utilisateur, donc on ne les connait pas à l’avance.

    Tu ne peux pas le faire comme ça, car ça va à l'encontre même de ce qu'une expression rationnelle représente. Une expression rationnelle est une écriture pratique permettant en pratique d'implémenter un automate fini déterministe, par définition sans mémoire. Dans ton cas, le test que tu veux faire requiert une mémoire (quelles lettres de
    $test1
    ) ont été effectivement rencontrées au moins une fois.

    La manière la plus simple (mais pas la plus efficace) de l'écrire en bash consiste à itérer sur chaque caractère de
    $test1
    , et vérifier avec
    grep
    si
    $chaine1
    le contient. Dès qu'on échoue, on arrête et on retourne "nok". Si on parvient à trouver toutes les lettres avec succès, on renvoie "ok".

    Pour moi bash n'est pas très pratique pour répondre à ce problème, je me tournerais plutôt vers un langage un peu plus évolué, comme par exemple python, qui permet de facilement transformer une chaîne en un ensemble de lettre et faire des tests d'inclusion.

    test1 = "ter"
    chaine1 = "pole"
    print("ok" {a for a in test1} <= {a for a in chaine1} else "nok")


    Bonne chance
    1