\( %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Mes commandes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcommand{\multirows}[3]{\multirow{#1}{#2}{$#3$}}%pour rester en mode math \renewcommand{\arraystretch}{1.3}%pour augmenter la taille des case \newcommand{\point}[1]{\marginnote{\small\vspace*{-1em} #1}}%pour indiquer les points ou le temps \newcommand{\dpl}[1]{\displaystyle{#1}}%megamode \newcommand{\A}{\mathscr{A}} \newcommand{\LN}{\mathscr{N}} \newcommand{\LL}{\mathscr{L}} \newcommand{\K}{\mathbb{K}} \newcommand{\N}{\mathbb{N}} \newcommand{\Z}{\mathbb{Z}} \newcommand{\Q}{\mathbb{Q}} \newcommand{\R}{\mathbb{R}} \newcommand{\C}{\mathbb{C}} \newcommand{\M}{\mathcal{M}} \newcommand{\D}{\mathbb{D}} \newcommand{\E}{\mathcal{E}} \renewcommand{\P}{\mathcal{P}} \newcommand{\G}{\mathcal{G}} \newcommand{\Kk}{\mathcal{K}} \newcommand{\Cc}{\mathcal{C}} \newcommand{\Zz}{\mathcal{Z}} \newcommand{\Ss}{\mathcal{S}} \newcommand{\B}{\mathbb{B}} \newcommand{\inde}{\bot\!\!\!\bot} \newcommand{\Proba}{\mathbb{P}} \newcommand{\Esp}[1]{\dpl{\mathbb{E}\left(#1\right)}} \newcommand{\Var}[1]{\dpl{\mathbb{V}\left(#1\right)}} \newcommand{\Cov}[1]{\dpl{Cov\left(#1\right)}} \newcommand{\base}{\mathcal{B}} \newcommand{\Som}{\textbf{Som}} \newcommand{\Chain}{\textbf{Chain}} \newcommand{\Ar}{\textbf{Ar}} \newcommand{\Arc}{\textbf{Arc}} \newcommand{\Min}{\text{Min}} \newcommand{\Max}{\text{Max}} \newcommand{\Ker}{\text{Ker}} \renewcommand{\Im}{\text{Im}} \newcommand{\Sup}{\text{Sup}} \newcommand{\Inf}{\text{Inf}} \renewcommand{\det}{\texttt{det}} \newcommand{\GL}{\text{GL}} \newcommand{\crossmark}{\text{\ding{55}}} \renewcommand{\checkmark}{\text{\ding{51}}} \newcommand{\Card}{\sharp} \newcommand{\Surligne}[2]{\text{\colorbox{#1}{ #2 }}} \newcommand{\SurligneMM}[2]{\text{\colorbox{#1}{ #2 }}} \newcommand{\norm}[1]{\left\lVert#1\right\rVert} \renewcommand{\lim}[1]{\underset{#1}{lim}\,} \newcommand{\nonor}[1]{\left|#1\right|} \newcommand{\Un}{1\!\!1} \newcommand{\sepon}{\setlength{\columnseprule}{0.5pt}} \newcommand{\sepoff}{\setlength{\columnseprule}{0pt}} \newcommand{\flux}{Flux} \newcommand{\Cpp}{\texttt{C++\ }} \newcommand{\Python}{\texttt{Python\ }} %\newcommand{\comb}[2]{\begin{pmatrix} #1\\ #2\end{pmatrix}} \newcommand{\comb}[2]{C_{#1}^{#2}} \newcommand{\arrang}[2]{A_{#1}^{#2}} \newcommand{\supp}[1]{Supp\left(#1\right)} \newcommand{\BB}{\mathcal{B}} \newcommand{\arc}[1]{\overset{\rotatebox{90}{)}}{#1}} \newcommand{\modpi}{\equiv_{2\pi}} \renewcommand{\Re}{Re} \renewcommand{\Im}{Im} \renewcommand{\bar}[1]{\overline{#1}} \newcommand{\mat}{\mathcal{M}} \newcommand{\und}[1]{{\mathbf{\color{red}\underline{#1}}}} \newcommand{\rdots}{\text{\reflectbox{$\ddots$}}} \newcommand{\Compa}{Compa} \newcommand{\dint}{\dpl{\int}} \newcommand{\intEFF}[2]{\left[\!\left[#1 ; #2\right]\!\right]} \newcommand{\intEFO}[2]{\left[\!\left[#1 ; #2\right[\!\right[} \newcommand{\intEOF}[2]{\left]\!\left]#1 ; #2\right]\!\right]} \newcommand{\intEOO}[2]{\left]\!\left]#1 ; #2\right[\!\right[} \newcommand{\ou}{\vee} \newcommand{\et}{\wedge} \newcommand{\non}{\neg} \newcommand{\implique}{\Rightarrow} \newcommand{\equivalent}{\Leftrightarrow} \newcommand{\Ab}{\overline{A}} \newcommand{\Bb}{\overline{B}} \newcommand{\Cb}{\overline{C}} \newcommand{\Cl}{\texttt{Cl}} \newcommand{\ab}{\overline{a}} \newcommand{\bb}{\overline{b}} \newcommand{\cb}{\overline{c}} \newcommand{\Rel}{\mathcal{R}} \newcommand{\superepsilon}{\varepsilon\!\!\varepsilon} \newcommand{\supere}{e\!\!e} \makeatletter \newenvironment{console}{\noindent\color{white}\begin{lrbox}{\@tempboxa}\begin{minipage}{\columnwidth} \ttfamily \bfseries\vspace*{0.5cm}} {\vspace*{0.5cm}\end{minipage}\end{lrbox}\colorbox{black}{\usebox{\@tempboxa}} } \makeatother \def\ie{\textit{i.e. }} \def\cf{\textit{c.f. }} \def\vide{ { $ {\text{ }} $ } } %Commande pour les vecteurs \newcommand{\grad}{\overrightarrow{Grad}} \newcommand{\Vv}{\overrightarrow{v}} \newcommand{\Vu}{\overrightarrow{u}} \newcommand{\Vw}{\overrightarrow{w}} \newcommand{\Vup}{\overrightarrow{u'}} \newcommand{\Zero}{\overrightarrow{0}} \newcommand{\Vx}{\overrightarrow{x}} \newcommand{\Vy}{\overrightarrow{y}} \newcommand{\Vz}{\overrightarrow{z}} \newcommand{\Vt}{\overrightarrow{t}} \newcommand{\Va}{\overrightarrow{a}} \newcommand{\Vb}{\overrightarrow{b}} \newcommand{\Vc}{\overrightarrow{c}} \newcommand{\Vd}{\overrightarrow{d}} \newcommand{\Ve}[1]{\overrightarrow{e_{#1}}} \newcommand{\Vf}[1]{\overrightarrow{f_{#1}}} \newcommand{\Vn}{\overrightarrow{0}} \newcommand{\Mat}{Mat} \newcommand{\Pass}{Pass} \newcommand{\mkF}{\mathfrak{F}} \renewcommand{\sp}{Sp} \newcommand{\Co}{Co} \newcommand{\vect}[1]{\texttt{Vect}\dpl{\left( #1\right)}} \newcommand{\prodscal}[2]{\dpl{\left\langle #1\left|\vphantom{#1 #2}\right. #2\right\rangle}} \newcommand{\trans}[1]{{\vphantom{#1}}^{t}{#1}} \newcommand{\ortho}[1]{{#1}^{\bot}} \newcommand{\oplusbot}{\overset{\bot}{\oplus}} \SelectTips{cm}{12}%Change le bout des flèches dans un xymatrix \newcommand{\pourDES}[8]{ \begin{itemize} \item Pour la ligne : le premier et dernier caractère forment $#1#2$ soit $#4$ en base 10. \item Pour la colonne : les autres caractères du bloc forment $#3$ soit $#5$ en base 10. \item A l'intersection de la ligne $#4+1$ et de la colonne $#5+1$ de $S_{#8}$ se trouve l'entier $#6$ qui, codé sur $4$ bits, est \textbf{\texttt{$#7$}}. \end{itemize} } \)

Les REGEX, pour REGular EXpressions, sont un ensemble de commande permettant d'effectuer des recherches dans les chaines de caractères. Par exemple, nous avons demandé à un utilisateur d'entrer une adresse mail. Nous voulons nous assurer que la chaine de caractères saisi est au bon format \[ \underbrace{\texttt{hebert.iut}}_{\text{(Des caractères)}} \underbrace{\texttt{\at}}_{\text{(un arobase)}} \underbrace{\texttt{gmail}}_{\text{(au moins 2 caractères)}} \underbrace{\texttt{.}}_{\text{(un point)}} \underbrace{\texttt{com}}_{\text{(entre 2 et 4 caractères)}}\] Pour éviter de faire une recherche "à la main" à l'aide de boucle TANT QUE, on peut utiliser la REGEX suivante (en PHP par exemple)1 :
preg_match("#^[a-zA-Z0-9]+@[a-zA-Z0-9]{2,}\.[a-z]{2,4}#",$chaine_saisi)
La fonction preg_match retourne vrai si la REGEX passé en paramètre apparait dans la chaine du second paramètre. Il existe beaucoup d'autre fonction permettant de jouer avec les REGEX permettant de récupérer ou substituer des informations.
Mémento sur les REGEX.
Ce n'est pas l'objectif de ce cours mais gardons en tête quelques commande.
REGEX Renvoie true si la chaine
#Euler#contient le mot Euler
#Euler|euler#contient le mot Euler ou euler
#[Ee]uler#contient le mot Euler ou euler
#^Euler#commence par Euler
#Euler$#finie par Euler
#^Euler$#ne contient que le mot Euler
#[a-z]#contient un lettre minuscule
#[0-9]#contient un chiffre
#[1-3a-gF-H]#contient un 1 ou 2 ou 3 ou une lettre minuscule parmi a, b, c, d, e, f, g ou une lettre majuscule parmi F, G, H
#[^XYZ]#ne contient pas X ou Y ou Z
#[^A-Z]#ne contient pas de lettre majuscule
#^[^a-z]#ne commence pas par une lettre minuscule
#[^Euler]$#ne finie pas E ou u ou l ou e ou r
#Ha{2,4}#contient le mot Haa ou Haa ou Haaa
#(Ha){2,4}#contient le mot HaHa ou HaHaHa ou HaHaHaHa
#Ha+#contient le mot qui commence par H suivit d'au moins un a. Cette REGEX équivaut à #Ha{1,}#
#Ha?#contient le mot H ou le mot Ha. Cette REGEX équivaut à #Ha{0,1}#
#Ha*#contient le mot H ou Ha ou Haa ou... . Cette REGEX équivaut à #Ha{0,}#
#Goo*gle#contient le mot Gogle ou Google ou Gooogle ...
#ang?e#contient le mot ange ou ane
#Allo\?#contient le mot Allo?
Liens entre langage rationnel et REGEX
L'idée est de déterminer une REGEX qui permet de reconnaitre tous les mots d'un langage rationnel. Comme nous l'avons survoler précédement, une REGEX est un mot sur un alphabet augmenter de quelques opération. Comme on le voit dans le tableau précédent, en plus des caractère alphanumérique de notre alphabet, on utilise un ensemble de caractère spéciaux (le dollar, le crochet, la parenthèse etc). Dans le cadre théorique dans lequel nous allons aborder ces REGEX, nous allons légèrement simplifier.

Définition


Soit \( \Sigma\) un alphabet. On définit l'alphabet augmenté \[\Sigma^+ = \Sigma \cup \{\varnothing, \varepsilon, (, ), +, *\}\]

Remarque

Pourquoi ces ajouts et pas d'autres ? L'idée est de trouver une correspondance parfaite entre les REGEX et les langages rationnels.
\( \bullet\)
L'ajout de \( \varnothing\) et \( \varepsilon\) va permettre d'avoir une REGEX qui correspond aux langages rationnels \( \varnothing\) et \( \{\varepsilon\}\) .

\( \bullet\)
L'ajout du \( +\) correspondra à l'union des langages

\( \bullet\)
L'ajout de \( *\) correspondra à l'étoile de Kleene

\( \bullet\)
Les parenthèses permettront de prioriser les opération (notamment entre la concaténation (équivalent d'une multiplication) et l'addition).

Définition


Soit \( \Sigma\) un alphabet. On note \( RE(\Sigma)\) l'ensemble des REGEX, mots sur \( \Sigma^+\) , construit de la manière suivante. \begin{eqnarray*} & &\varnothing\in RE(\Sigma)\\ & &\varepsilon\in RE(\Sigma)\\ \forall x\in \Sigma & & x\in RE(\Sigma)\\ \forall e_1, e_2\in RE(\Sigma) & & (e_1 + e_2) \in RE(\Sigma)\\ \forall e_1, e_2\in RE(\Sigma) & & (e_1e_2) \in RE(\Sigma)\\ \forall e\in RE(\Sigma) & & e^* \in RE(\Sigma) \end{eqnarray*}

Remarque

Une autre manière de lire cette définition est :
  1. L'ensemble vide est une REGEX
  2. Le mot vide est une REGEX
  3. Toutes les lettres sont des REGEX
  4. La somme de REGEX est une REGEX
  5. La concaténation de REGEX est une REGEX
  6. L'étoile de Kleene d'une REGEX est une REGEX

Remarque

Attention, si \( e\) et \( f\) sont des REGEX alors \( e+f\) n'est pas une REGEX. En effet, la règle de l'addition dis que la REGEX est \( (e+f)\) (les parenthèses). Mais dans la pratique que nous allons en faire, la manipulation répétitive du parenthésage peut devenir très lourde. Nous convenons donc de nous libérer de cette contrainte lorsqu'il n'y aura pas d'ambiguïté en considérant que la concaténation est prioritaire sur l'addition. Ainsi \( ef+g\) aura un sens, celui de \( ((ef)+g)\) et \( e(f+g)\) aura le sens de \( (e(f+g))\) .
Voici le résultat tant attendu.

Théorème


Soit \( \Sigma\) un alphabet. Il existe une unique application langage associé, noté \( L\) , satisfaisant les conditions suivantes : \[ \begin{array}{lrcl} &L : RE(\Sigma) & \longrightarrow & LR(\Sigma)\\ &\varnothing & \longmapsto & \varnothing\\ &\varepsilon & \longmapsto &\{\varepsilon\}\\ \forall x\in \Sigma, & x & \longmapsto &\{x\}\\ \forall e_1, e_2\in RE(\Sigma),& (e_1+e_2) & \longmapsto & L(e_1)\cup L(e_2)\\ \forall e_1, e_2\in RE(\Sigma), & (e_1e_2)& \longmapsto & L(e_1)L(e_2) \in RE(\Sigma)\\ \forall e\in RE(\Sigma), & e^* & \longmapsto & L(e)^* \in RE(\Sigma) \end{array} \] De plus cette application est surjective.

Démonstration

Admise.

Remarque

Une autre manière de lire les règles de la fonction langage associé est :
  1. \( L\left(\varnothing\right)=\varnothing\)
  2. \( L\left(\varepsilon\right)=\{\varepsilon\}\)
  3. \( \forall x \in \Sigma\) , \( L\left(x\right)=\{x\}\)
  4. \( \forall e_1, e_2\in RE(\Sigma)\) , \( L\left(e_1\right)\cup L\left(e_2\right)=L(e_1+e_2)\)
  5. \( \forall e_1, e_2\in RE(\Sigma)\) , \( L\left(e_1\right)L\left(e_2\right)=L\left(e_1e_2\right)\)
  6. \( \forall e\in RE(\Sigma)\) , \( L\left(e\right)^*=L\left(e^*\right)\)

Remarque

La surjectivité de l'application langage associé se reformule en disant qu'il existe (au moins) une REGEX à tout langage rationnel.

Exemple


Sur l'alphabet \( \Sigma=\{a, b, c\}\) quel est le langage rationnel associé à la REGEX \( ab+c\) ? La question reviens à calculer \( L(ab+c)\) , en utilisant les règles de la fonction \( L\) on a \begin{eqnarray*} L(ab+c) &=& L(ab)\cup L(c)\\ &=& L(a)L(b)\cup L(c)\\ &=& \{a\}\{b\}\cup \{c\}\\ &=& \{ab\}\cup \{c\}\\ &=& \{ab, c\}\\ \end{eqnarray*}

Exercice


On fixe l'alphabet \( \Sigma=\{a, b, c\}\) . Pour chacune des REGEX suivantes déterminer le langage rationnel.
  1. \( \varepsilon\)
  2. \( a\)
  3. \( a+b\)
  4. \( ab+c\)
  5. \( a(b+c)\)
  6. \( a^*\)
  7. \( (ab)^*\)
  8. \( (a+b)^*\)

Exercice


On fixe l'alphabet \( \Sigma=\{a, b, c\}\) . Déterminer, si possible, une REGEX associée aux langages suivantes.
  1. \( L=\{\varepsilon\}\)
  2. \( L=\{a, b, c\}\)
  3. \( L=\{a, ab, ac\}\)
  4. \( L=\{a^n | n\in \N\}\)
  5. \( L=\{a^{2n} | n\in \N\}\)
  6. \( L=\{b, ab, aab, aaab, aaaab, \ldots\}\)
  7. \( L=\{c, b, ab, aab, aaab, aaaab, \ldots\}\)




1 Le langage de REGEX utilisé ici est le BRE (Basic Regular Expression), il en existe d'autre comme par exemple le ERE (Extended Regular Expression), le PCRE (Perl Compatible Regular Expressions) fort de sa comptatibilité avec le langage java.