Probleme de regex

Fermé
lamouchetsetse Messages postés 112 Date d'inscription samedi 2 août 2014 Statut Membre Dernière intervention 21 septembre 2021 - Modifié le 27 déc. 2017 à 17:41
mamiemando Messages postés 33077 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2024 - 31 déc. 2017 à 18:12
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

mamiemando Messages postés 33077 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2024 7 748
31 déc. 2017 à 18:12
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