Sur une distribution Debian ou Ubuntu récente, nous vous conseillons de réinstaller totalement votre serveur si cela est possible sur votre machine. Attention, cette action effacera totalement vosdonnées.
Connectez-vous en SSH en tant qu’administrateur « root ». N’hésitez pas à vous reporter au guideSSH.
Une fois le système installé, il convient de le mettre à jour :
apt-get update && apt-get upgrade -y
Vous partez ainsi sur une base saine et totalement àjour.
Étape 2 : créez un nouvel utilisateur avec les privilèges« sudo »
Pour des raisons de sécurité et pour suivre les bonnes pratiques, il est préférable d’installer et gérer un serveur LAMP avec un utilisateur séparé, ne possédant pas les privilèges « root ». Si vous disposez déjà d’un utilisateur avec les privilèges « sudo », sans pour autant être « root », vous pouvez vous rendre directement à la deuxième étape. Ce type de fonctionnement est déjà en vigueur pour les dernières versionsd’Ubuntu.
Dans le cas où vous ne possédez que l’utilisateur « root », il convient de créer un nouvel utilisateur:
adduser mynewuser
Diverses informations seront obligatoires, comme un mot de passe. D’autres seront optionnelles : le nom ou le numéro de téléphone, parexemple.
Il faut ensuite rajouter cet utilisateur au groupe « sudo »:
usermod -aG sudo mynewuser
Et enfin, connectez-vous sur ce nouveau compte utilisateur:
su - mynewuser
Étape 3 : installation du serveur web Apache2
La première brique du stackLAMP, le système d’exploitation Linux, a été installée lors des étapes précédentes.
Nous allons installer ici la deuxième brique, le serveur web Apache 2, ainsi que sa documentation:
sudo apt-get install apache2 apache2-doc
Si l’installation s’est effectuée correctement, vous devriez pouvoir accéder à la page par défaut d’Apache en joignant l’adresse IP (ou le nom du service) de votre serveur dans le navigateur, comme suit : http://IP_du_serveur. N’essayez pas de vous connecter en HTTPS, car à ce stade aucun certificat SSL n’est encoreinstallé.
Cette page est très instructive, et vous donnera un aperçu des fichiers de configuration d’Apache 2 et leur spécificités. N’hésitez pas à laparcourir.
Il est possible de vérifier que le service Apache fonctionne correctement en utilisant la commande suivante:
sudo service apache2 status
La mention active (running) doit apparaître.
La procédure Apache peut se gérer comme suit :
service apache2 start=> permet de démarrer le service
service apache2 stop=> permet d’arrêter le service
service apache2 restart=> permet de relancer ou recharger le service
Étape 4 : installezPHP
Nous passons ensuite à l’installation de la troisième brique, le langage de programmationPHP.
Pour installer le paquet PHP, tapez cette commande:
Vous devriez pouvoir visualiser une page détaillant toutes les spécificités de votre environnement PHP (version 7.0.30 dans notre cas):
Une fois visualisé, nous vous recommandons vivement de supprimer le fichier index.php. En effet, il n’est jamais conseillé de donner publiquement des informations sur votreconfiguration.
Par défaut, le serveur web Apache ne priorise pas les fichiers PHP par rapport aux fichiers HTML. Ici, dans le dossier racine, nous disposons de index.html et de index.php. Si vous retournez dans votre navigateur web, sur http://IP_du_serveur, Apache vous renverra la page index.html et non pas index.php. Cette priorisation n’a pas d’impact sur la majeure partie des CMS comme WordPress ou Drupal. Ces règles peuvent toutefois être modifiées si besoin.
Étape 5 : installez le système de base de donnéesMySQL/MariaDB
Nous arrivons à la quatrième et dernière brique du stackLAMP, le système de bases dedonnées.
Depuis le rachat de MySQL par Oracle, le fondateur de MySQL a créé en 2009 un dérivé (fork en anglais) plus communautaire et plus ouvert, appelé MariaDB en hommage à sa deuxième fille. 100 % des commandes MySQL sont compatibles avec MariaDB, tout comme vos applicatifs web préférés. La distribution Linux Debian propose MariaDB par défaut. Si vous utilisez ce système d’exploitation, vous pourrez lire « MariaDB » dans votre terminal lors de cette étape.
Voici la commande à utiliser (votre mot de passe de compte utilisateur Linux vous sera demandé):
sudo apt-get install mysql-server
Par défaut, le mot de passe administrateur MySQL/MariaDB sera le même que celui de votre utilisateur système. Pour personnaliser la sécurisation de votre base de données, voici la commande à effectuer:
mysql_secure_installation
Entrez votre mot de passe « root », puis changez le mot de passe:
Change the root password? [Y/n]=> y
New password:
Désactivez ensuite les connexions anonymes:
Remove anonymous users? [Y/n]=> y
Désactivez la connexion en « root » depuis une connexion distante:
Disallow root login remotely? [Y/n]=> y
Il faut maintenant effacer la base de données de test créée par défaut:
Remove test database and access to it? [Y/n]=> y
Il reste à charger les nouveaux paramètres:
Reload privilege tables now? [Y/n]=> y
Pour tester l’accès à votre base de données, voici la commande à utiliser dans votre terminal:
mysql -u root -p
MariaDB [(none)]> show databases;
MariaDB [(none)]> exit
Nous vous conseillons de créer un utilisateur spécifique et dédié à votre applicatif web. Si besoin, référez-vous à la documentation officielle MySQL ou MariaDB.
Étape 6 : installez phpMyAdmin(optionnel)
L’installation du serveur LAMP est terminée ! Cette étape est optionnelle. L’interface open source phpMyAdmin va vous permettre de gérer plus facilement vos bases de données via une interfaceweb.
Pour l’installer voici la commande à entrer:
sudo apt-get install phpmyadmin
Dans les choix proposés, sélectionnez un serveur web à reconfigurer automatiquement pour exécuter phpMyAdmin :
cochez ()apache2, puis Entrée ;
acceptez l’aide à la configuration, puis rentrez un mot de passe administrateurMySQL.
Afin d’accéder à l’interface de gestion de phpMyAdmin, vous devrez finaliser la configuration votre serveur Apache. Pour cela, éditez le fichier de configuration Apache:
sudo nano /etc/apache2/apache2.conf
À la fin du fichier, rajoutez:
# Include phpMyAdmin
Include /etc/phpmyadmin/apache.conf
Le service Apache doit ensuite être relancé grâce à cette commande:
sudo service apache2 restart
Afin de vous connecter, vous devrez au préalable créer un utilisateur possédant les droits administrateur pour phpMyAdmin :
mysql -u root -p
[mot de passe]
MariaDB [(none)]> CREATE USER 'my_user'@'localhost' IDENTIFIED BY 'my_password';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON * . * TO 'my_user'@'localhost';
MariaDB [(none)]> FLUSH PRIVILEGES;
Créez une base nommée wordpress en ligne de commande ou via phpMyAdmin.
Votre écran de configuration doit ressembler à celui ci-dessous:
Si vous avez un avertissement au niveau de la création du fichier wp-config.php, éditez les droits en exécution, lecture, écriture en fonction de vos besoins (communément appelés CHMOD).
Conclusion
Voilà, le CMS WordPress est installé et est propulsé par votre stack LAMP installé dans ce tutoriel!
Nous venons d’installer un serveur LAMP en partant de zéro, vous permettant ainsi d’héberger vous-même vos sites et applications web. En réalisant cette installation par vos propres moyens, vous gardez une liberté de configuration totale. N’hésitez pas à lire la documentation officielle d’Apache pour en découvrir toutes lespossibilités.
Si vous désirez aller plus loin ou que vous êtes curieux, sachez qu’il existe des alternatives à Apache : la plus connue au succès grandissant étant NGNIX (prononcez « engine-x »). Un stack incluant NGINX est appelé LEMP, et est souvent réputé pour être plus léger. Nous vous conseillons enfin de sécuriser votre site avec un certificatSSL.
Step 1: Connect to your server via SSH and update your server OS packages
Before we begin, let’s connect to your VPS via SSH as user root and update your Ubuntu OS packages to the latest available version.
To connect to your server via SSH as user root, use the following command:
ssh root@IP_ADDRESS -p PORT_NUMBER
Replace “IP_ADDRESS” and “PORT_NUMBER” with your actual server IP address and SSH port number.
Once logged in, make sure that your server OS packages are up-to-date by running the following commands:
apt-get update
apt-get upgrade
If this is your first time logging into your brand new Ubuntu VPS, you can also check our First Steps After Getting An Ubuntu VPS tutorial for some additional basic initial server setup and security tips.
Step 2: Install a Web Server
In this section, we will show you how to install a web server on your VPS. We can install Apache, or nginx as a web server. For the purpose of this tutorial, we will install the Apache web server. Apache is a fast and secure web server and one of the most popular and widely used web server in the world.
To install the Apache web server, run the following command on your server:
apt-get install apache2
After the installation is complete, you should start Apache:
systemctl start apache2
Also, you can enable Apache to start automatically on server boot:
systemctl enable apache2
To check the status of the Apache web server and make sure it is up and running, you can use the following command:
systemctl status apache2
To verify that Apache is running, you can also open your web browser and enter your server IP address, (e.g. http://your_server_ip_address). If Apache is successfully installed, you should see the Apache default welcome page.
Step 3: Install Ondřej Surý’s PPA
PHP 7.2 can be installed using Ondřej Surý’s PPA, so install the software-properties-common and python-software-properties packages:
Use the following command to check the PHP version installed on your server:
php -v
You should receive the following output:
PHP 7.2.9-1+ubuntu16.04.1+deb.sury.org+1 (cli) (built: Aug 19 2018 07:16:12) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.2.9-1+ubuntu16.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies
Now, PHP 7.2 has been installed on your Ubuntu server, and if we want to change the default PHP version to PHP 7.2 that is used by the web server, we need to disable the old PHP 7.0 version and enable the newly installed one.
Disable PHP 7.0
a2dismod php7.0
Enable PHP 7.2
a2enmod php7.2
Restart the Apache web server for the changes to take effect:
systemctl restart apache2
To test your installation and check that Apache, PHP and PHP extensions are working properly, create a new php info file:
vi /var/www/html/phpinfo.php
Add the following content to it:
<?php phpinfo(); ?>
Open the ‘phpinfo.php’ file using a web browser:
http://<ip-address>/phpinfo.php or http://<your-domain.com>/phpinfo.php
and view the current information about PHP on your server. That’s it. You have successfully installed PHP 7.2 on an Ubuntu 16.04 server. For more information about PHP 7, please refer to the official PHP documentation.
La numérotation se fait de gauche à droite, et pour un groupe, elle est égale au nombre total de parenthèses ouvrantes qui le précède.
#!/usr/bin/python3
import re
texte = \" abcdefghijklmnopqrstuvwxyz \"
patron = \"abc(def(ghi)(jkl))(mno)pqr\"
cpatron = re.compile(patron)
res = cpatron.search(texte)
if res :
try:
for i inrange (99) : # maximum de 99 groupes
print (\"groupe\", i , \":\", res.group(i))
except:
pass
Ecrire et tester le code.
Justifier les résultats.
Attention : Si le patron comporte un ou logique la règle de numérotation continue à s'appliquer. Par exemple, le patron \"ab(c)d|xy(z)\" comporte deux groupes : numérotés 1 (c) et 2 (z).
","title":"Règle de numérotation des groupes"},{"edit":"
","title":"Nommer les groupes"},{"edit":" "}],[{"text":"
Lorsqu'un groupe est identifié à un segment de chaîne, la valeur de la sous-chaîne identifiée peut être \"capturée\", et utilisée dans l'expression régulière et dans la fonction de remplacement sub().
La valeur reconnue se désigne dans l'expression régulière par un antislash suivi de son numéro
(exemple : \\5 pour la chaîne du groupe 5) ou par la convention de nommage :
(?P=identificateur)
Mais l'antislash suivi d'un chiffre peut avoir une signification en Python, il faut donc doubler l'antislash dans la chaîne Python. Par ailleurs, cette notation devient ambiguë avec les valeurs au delà de 10.
Comment
est interprèté \\14 ? groupe 1 suivi de 4 ou groupe 14 ? Dans le patron le nombre à deux chiffres est correctement interprété comme \"groupe 14\" ; le groupe 1 suivi de 4 doit s'écrire par exemple \\\\1[4].
","title":"Capture des groupes."},{"edit":" "}],[{"text":"
Problème : trouver les mots d'un texte qui commencent et se terminent par la même lettre.
import re
texte = \"J'ai été en sursis et j'irai bien désormais\"
patron = \"\\\\b(\\w).*?\\\\1\\\\b\"
cpatron = re.compile(patron)
whileTrue :
print (texte)
res = cpatron.search(texte)
if res :
print (res.group(0))
texte = texte [res.end():]
else: break
On a figuré le groupe et la chaîne dont l'identification relève de l'analyse syntaxique.
","title":"Exemple d'usage du numéro"},{"edit":" "}],[{"text":"
#!/usr/bin/python3
import re
texte = \"J'ai été en sursis et j'irai bien désormais\"
","title":"Usage de la convention de nommage. exemple"},{"edit":" "}],[{"text":"
On peut utiliser les éléments capturés dans la chaîne de remplacement.
Les conventions de nommage sont alors :
\\g<identificateur>
\\g<numéro>
Les symboles < et > ne sont pas indispensables si le numéro n'a qu'un chiffre ; mais cette facilité est à éviter à cause de l'ambiguïté qui naît avec les valeurs à deux chiffres.
Voici un problème d'illustration : on dispose d'un texte html, et on veut remplacer l'expression align=center par une autre chaîne, mais uniquement dans les balises de bloc de texte, c'est-à-dire commençant par h0,h1 ...h9 ou p.
De plus, on veut éliminer tout le reste des attributs de ces balises.
import re
texte = \"\"\"<h1 name=\"titre\"
align=CENTER>align=center</h1>
<img src=\"kw154.png\" align = center>
<p align = center id=\"zazozi\" >wawawa</p>
<h2 align= center>fin de texte</h2>\"\"\"
print(\"La page html :\", texte)
patron = \"\"\"
(<h\\d|<p) # balise commençant par <h avec chiffre ou <p
# les deux groupes sont utilisés dans la chaîne de remplacement.
res = cpatron.sub('\\g<1> style=\\'align:center;\\' \\g<2>', texte)
print(res)
Ecrire et tester le code ci-dessous.
Justifier le résultat.
","title":"La fonction de remplacement sub() avec capture"},{"edit":" "}],[{"text":"
Le problème :
Supposons que l'on dispose de l'expression régulière patron mais que l'on veuille chercher une correspondance conditionnelle : seulement si l'expression à trouver est \"suivie\" (ou n'est pas suivie) d'une expression trouvée avec une autre expression régulière hpatron.
Par exemple, on cherche la chaîne \"Isaac\" suivie par \"Newton\" ou \"Asimov\". Ou le contraire. Évidemment, on peut compliquer un peu.
Une telle recherche s'appelle un lookahead. Sa caractéristique essentielle est qu'elle ne consomme que la chaîne recherchée, pas la chaîne conditionnelle.
","title":"Lookahead positif ou négatif"},{"edit":" "}],[{"text":"
Lookahead postposé
#!/usr/bin/python3
import re
texte = \"isaac jacob, Isaac Newton, Isaac Asimov,\\
isaac isaac\\n, isaac Isaac\"
print(\"le texte :\", texte)
patron =\"Isaac\\s(?=Asimov|Newton)\"
cpatron = re.compile(patron, re.IGNORECASE)
print (cpatron.findall(texte))
patron =\"Isaac(?:\\s|$)(?!Asimov|Newton)\"
cpatron = re.compile(patron, re.IGNORECASE)
print (cpatron.findall(texte))
Ecrire et tester le code.
Justifier les résultats.
Remarques :
- \\s pour un blanc (espace, fin de ligne).
- on voit bien sur le second cas qu'il n'y a pas consommation du lookahead.
","title":"Exemple :"},{"edit":" "}],[{"text":"
lookahead préposé. exemple 2 :
#!/usr/bin/python3
import re
texte = \"isaac jacob, IsaacNewton, Isaac Asimov, bellisaac\"
patron =\"(?=\\\\bisa\\w*\\\\b)isaac\"
cpatron = re.compile(patron, re.IGNORECASE)
print (cpatron.findall(texte))
Ecrire et tester le code ci-dessus.
Quelle est la différence avec l'exemple précédent.
Remarque :
e patron du lookahead est d'abord recherché ; s'il est trouvé, la recherche de la seconde partie du patron se fait à partir du premier élément trouvé, qui est ici un début de mot. On dit qu'il y a chevauchement.
","title":"Exemple avec lookahead préposé"},{"edit":" "}],[{"text":"
Une recherche de correspondance avec comme condition de suivre (ou non) une correspondance définie par une autre expression régulière est un lookbehind.
Le lookbehind consomme l'expression précédente, mais ne la retourne pas. Il n'y a pas de chevauchement avec le lookbehind, car la chaîne conditionnelle est avant la chaîne recherché.
Restriction :
- l'expression qui sert de condition doit avoir une longueur préfixée;
- on ne peut avoir de .* ou \\w* ;
- on peut avoir toto|titi.
Sinon, Il y a erreur à la compilation.
La syntaxe est la suivante:
(?<=expression lookbehind recherchée)
(?<!expression lookbehind rejetée)
","title":" Lookbehind positif ou négatif"},{"edit":" "}],[{"text":"
On a donc les 4 schémas possibles suivants quand on veut utiliser des conditions :
"},{"edit":" "}],[{"text":"Les expressions régulières sont des outils très puissants en informatique pour le traitement des chaînes de caractères. Nous avons vu qu'elles permettent donc de chercher, de trouver des correspondances, de découper, de remplacer à l'aide de motif et de patron dans des textes. Par ailleurs, vous pourrez les utiliser dans d'autre langage comme le C, javascript, php, ...
","title":"Conclusion"},{"edit":""}],[{"text":"
Write a Python program to check that a string contains only a certain set of characters (in this case a-z, A-Z and 0-9). Go to the editor
Write a Python program to search a literals string in a string and also find the location within the original string where the pattern occurs. Go to the editor
Sample text : 'The quick brown fox jumps over the lazy dog.' Searched words : 'fox'
Write a Python program to remove the parenthesis area in a string. Go to the editor Sample data : [\"example (.com)\", \"w3resource\", \"github (.com)\", \"stackoverflow (.com)\"] Expected Output: example w3resource github stackoverflow Click me to see the solution
","title":"Exercice 9"},{"edit":"
Ecrire votre réponse ici.
"}],[{"text":"
Faites suivant et envoyez votre travail au format pdf à l'adresse mail ci-dessous :
Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.
Les opérateurs vus dans la séquence précédente permettent de répondre aux problèmes liés à la répétition d'un caractère. Le seul joker dont on dispose est le point (sous deux acceptions, avec ou sans fin de ligne). La première extension souhaitable est de diversifier les jokers.
","title":"Introduction"},{"edit":"
"}],[{"text":"
Les. jeux de caractères définis ou classes.
Au lieu de dire \"tout caractère\" comme avec le joker \"point\", on peut définir en extension un jeu de caractères. La syntaxe est simple :
[caractères du jeu]
Les caractères sont écrits en suivant, dans une suite sans espacements :
[abcABC$*+]
est le jeu (la classe) des 9 caractères a,b,c,A,B,C,$,*,+
Il n'est pas utile d'échapper les caractères litigieux des expressions régulières comme *, +, . etc.
C'est une bonne méthode de protection : on écrit [*] au lieu de \\*
Il existe une forme abrégée pour les séquences :
premier et dernier caractère séparés par un trait
d'union : [a-z] pour une minuscule, [A-Z] pour une majuscule, [0-9] pour un chiffre.
C'est ainsi que [a-zA-Z] équivaut à \"toute lettre ASCII\".
Le jeu [À-ÿ] est tout à fait valide.
Une définition de jeu peut être définie par exclusion :
il suffit de commencer par ^.
Par exemple :
- le jeu [^5] définit tout caractère sauf 5.
- [^0-9] : tout caractère sauf un chiffre.
Pour éviter certaines protections lourdes, on peut définir des jeux à un caractère :
[*], ou [+], ou [\\\\] ; cela remplace avantageusement \\* \\+ ou \\\\\\\\
Remarque : Le caractère ^ doit être protégé lorsque son utilisation est littérale, soit en début d'expression, soit en début de jeu de caractère : [\\^abcd]; [\\^]. On ne peut pas écrire [^].
","title":"Diversifier les jokers et marqueurs"},{"edit":"
"}],[{"text":"
Certaines classes sont prédéfinies, ainsi que certains marqueurs :
Jeu prédéfini
Signification
\\A
trouver uniquement au début de la chaîne. Ressemble à ^ mais n'est pas affecté par la directive MULTILINE.
\\b
\\b est réservé en python (c'est le backspace) ; il faut donc écrire \\\\b pour utiliser dans une chaîne Python. Le caractère qui suit est en début ou fin de mot.
\\B
le caractère qui suit n'est ni en début de mot, ni en fin de mot.
\\d
équivalent de [0-9]
\\D
tout caractère sauf un chiffre
\\s
équivaut à [ \\b\\t\\n\\r\\f\\v], espace, backspace, tabulation, fin de ligne(LF), début de ligne (CR), à la ligne (FF), tabulation verticale. On désigne parfois ces caractères comme des blancs.
\\S
tout caractère sauf ceux de \\s
\\w
équivalent à [a-zA-Z0-9_], caractères alphanumériques. Peut être affecté par la directive LOCALE.
\\W
tout caractère non alphanumérique
\\Z
trouve uniquement en fin de la chaîne. Ressemble à $ mais est insensible à la directive MULTILINE.
","title":"Classes et marqueurs usuels prédéfinis"},{"edit":"
"}],[{"text":"
En calcul numérique, on utilise les parenthèses pour hiérarchiser les opérations. Il en est de même pour les expressions régulières.
On peut parenthéser une sous-expression régulière et lui appliquer les opérateurs d'itération vus pour les caractères.
ATTENTION : Le parenthésage a une syntaxe peu intuitive et déroutante :
Problème : examiner si une chaîne est une adresse mail valide.
Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.
Une adresse mail comporte une ou deux chaînes alphanumériques ; dans ce second cas, un point les sépare.
Le caractère @ suit. La seconde partie est constituée d'une suite d'au moins deux chaînes alphanumériques séparées par un point.
import re
textes1 = [Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.', \"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\",
\"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\",'zorlubfree.fr']
textes2 = ['zorlub@free', \"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\",
\"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.. fr\",\"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser. \"]
g_patron = \"^\\w+(?:[.]\\w+)?\"# partie gauche
d_patron = \"\\w+(?:[.]\\w+)+$ \"# partie droite
cpatron = re.compile(g_patron+\"@\"+d_patron)
#teste les 2 listes de mails
for x in textes1 + textes2:
res = cpatron.search(x)
if res:
print (x, \"est correct\")
else:
print (x, \"n'est pas une adresse valide\")
Ecrire et tester le code ci-dessous.
Justifier la forme de l'expression régulière.
","title":"Application"},{"edit":"
Ecrire les résultats ici.
"}],[{"text":"
Deux analyses en pipeline.
Que se passe-t-il entre la lecture du source d'une expression régulière et l'édition d'un patron compilé qui est utilisé par les méthodes search(), match(), findall(), sub() et split()?
patron = chaîne_source
cpatron = compile(patron)
Il y a deux étapes au niveau lexical : l'analyseur de chaîne Python lit la chaîne source et la traite :
il en sort une chaîne interne dans le format de stockage de Python. C'est à ce niveau que sont traités les caractères spéciaux comme le backslash (\\b) et la fin de ligne (\\n).
Puis l'analyseur lexical de la machine d'analyse des expressions régulières prend le relai et isole les unités lexicales que comprend l'analyseur d'E.R.. Les jokers, les marqueurs, les expressions sont de telles unités lexicales.
On a figuré deux éléments qui relèvent de l'analyse syntaxique (classe, chaîne).
","title":"La double analyse lexicale"},{"edit":"
"}],[{"text":"
Lorsque Python réalise l'analyse lexicale d'une chaîne littérale pour en créer la représentation interne, il lit la représentation littérale (flot d'entrée) de gauche à droite pour en dégager les unités lexicales, qui seront ensuite codées comme un caractère (flot de sortie) :
- l'antislash en fin de ligne est ignoré (chaînes sur plusieurs lignes). Le changement de ligne qui suit est ignoré également.
Un analyseur lexical prend un flot de caractères sur son entrée standard, isole les unités lexicales, et envoie un flot d'unités lexicales sur sa sortie standard. Une unité lexicale peut être un identificateur, un mot réservé du langage, un signe (+ - * / ! etc), un délimiteur (parenthèse, accolade, crochet, /*, */ etc), c'est-à-dire toute unité pertinente pour l'analyse syntaxique.
- les unités lexicales tiennent en général sur un seul caractère ; c'est le cas des caractères alphanumériques ou des caractères accentués ou de la ponctuation par exemple.
- certaines unités ont besoin de deux caractères dans la chaîne littérale : par exemple la fin de ligne est notée \\n, le backspace \\b, la tabulation \\t. Ces couples correspondent à une seule unité lexicale (un caractère dans la chaîne interne).
- certaines peuvent tenir sur un ou deux caractères sans poser de difficulté : \\\" et \\'. En effet, les caractères \" et ' étant des délimiteurs, leur échappement par l'antislash permet de les considérer comme des littéraux. Ainsi si on pose :
maChaine ='papa \"Noël\" s\\'est envolé'
taChaine = 'papa \\\"Noël\\\" s\\'est envolé'
saChaine ='papa \\\"Noël\" s\\'est envolé'
print (maChaine==taChaine,maChaine==saChaine)
on peut vérifier que les trois chaînes sont similaires.
- la difficulté apparaît lorsque l'on utilise l'antislash. L'antislash peut s'échapper lui-même : c'est sans ambigüité ; même chose pour \" et '. Mais qu'en est-il s'il précède un caractère qui ne peut être échappé. Comme par exemple un espace,les caractères c, d, w, ...
L'antislash est alors considéré comme littéral !
exemple :
print(\"\\c\\d\\w\") donne : \\c\\d\\w
- enfin, plus délicat encore certaines séquences antislashées introduisent des séquences spécifiques, comme par exemple des séquences unicodes ou numériques (cas de \\u \\U \\x \\N)
Voici ce que dit la documentation officielle :
Escape Sequence
Meaning
\\newline
Backslash and newline ignored
\\\\
Backslash (\\)
\\'
Single quote (')
\\\"
Double quote (\")
\\a
ASCII Bell (BEL)
\\b
ASCII Backspace (BS)
\\f
ASCII Formfeed (FF)
\\n
ASCII Linefeed (LF)
\\r
ASCII Carriage Return (CR)
\\t
ASCII Horizontal Tab (TAB)
\\v
ASCII Vertical Tab (VT)
\\ooo
Character with octal value ooo
\\xhh
Character with hex value hh
Escape sequences only recognized in string literals are:
Escape Sequence
Meaning
\\N{name}
Character named name in the Unicode database
\\uxxxx
Character with 16-bit hex value xxxx
\\Uxxxxxxxx
Character with 32-bit hex value xxxxxxxx
Applications :
La chaîne \"\\123\" donne le caractère de code octal 123 en Unicode, soit S (code 64+2x8+3 = 83) :
print(ord(\"\\123\"), \"123\")
La chaîne \"\\u00b5\" donne le μ de code 181 :
print(ord(\"\\u00b5\"), \"\\u00b5\")
Tester et verifier les résultats des instructions ci-dessus.
Chaque caractère unicode a un nom (importer le module unicode):
D'où la liste des caractères alphanumériques pour lesquelles l'antislash n'est pas un littéral
On insiste bien sur le fait que l'analyse lexicale de Python s'applique à tout ce qui se trouve sur le flot d'entrée de l'analyseur, texte comme patron.
","title":"L'échappement dans les chaînes en Python."},{"edit":"
Ecrire les résultats ici.
"}],[{"text":"
Lors de la compilation, c'est la chaîne interne de Python qui est examinée par l'analyseur lexical du moteur d'analyse des expressions régulières.
Il y a alors le second niveau d'analyse, qui lui aussi utilise l'antislash pour caractère d'échappement ! Cela ne pose pas de problème avec ^, ( , ) , { , }, w, W, B, 8, 9, $. Il y en a un avec les caractères particuliers qu'il faut échapper à l'aide d'un \\\\ lors de la première analyse lexicale. Il faut prêter une attention particulière aux caractères b, 0, 1, 2, 3, 4, 5, 6, 7.
Quand à l'antislash, comme il est doublement caractère d'échappement, pour l'utiliser comme littéral, il vaut mieux l'échapper pour Python, puis pour l'analyse re, ce qui fait quatre antislash ! \\\\\\\\
","title":" L'échappement des expressions régulières"},{"edit":"
Ecrire ici vos résultats.
"}],[{"text":"
Le problème : les expressions régulières sont particulièrement indigestes. Parmi les faits qui
concourent à une lecture difficile on peut citer :
- l'absence de caractères d'aération, ce que l'on appelle parfois \"les blancs\" : espaces, tabulation, saut de ligne ;
- l'absence de commentaires explicatifs insérés dans l'expression ;
- les difficultés liées au fait que l'on cumule deux niveaux d'analyse : l'analyse lexicale de Python qui donne une première représentation de l'expression, puis l'analyse lexicale du moteur d'expressions régulières. La multiplication des échappements est liée à cet aspect de la question.
Cette difficulté de lecture peut être en partie levée par l'utilisation de techniques appartenant à l'un ou l'autre des analyseurs lexicaux.
Remarque : Dans les exemples qui suivent, la signification des expressions régulières n'a pas à être examinée. Ces exemples illustrent l'aération du patron.
- Caractères particuliers pour l'échappement N U u x 01 2 3 4 5 6 7 a b f n r v
","title":"Donner de l'air aux expressions régulières"},{"edit":"","css":"","js":""}],[{"text":"
En Python, on peut saisir une chaîne sur plusieurs lignes physiques ; il suffit de terminer chaque élément significatif du texte par un antislash suivi d'un passage à la ligne. Attention, après l'antislash il ne doit rien y avoir !
Il y a alors concaténation des segments de texte à l'analyse lexicale.
Application :
import re
textes = \"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,\\
Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\"
patron = \"\\\\b\\
\\w+\\
(?:[.]\\w+)?\\
@\\
\\w+\\
(?:[.]\\w+)*\\
[.](?:fr|com)\\
\\\\b\"
print(patron,\"\\n\")
cpatron = re.compile(patron)
print (cpatron.findall(textes))
Ecrire et tester le code ci-dessus.
Justifier la mise en forme du code.
","title":"La saisie multiligne des chaînes"},{"edit":"
Ecrire ici le résultat.
"}],[{"text":"
La syntaxe est (?# texte )
Le texte est un commentaire ; il est ignoré.
On doit prendre garde à ce que le commentaire en ligne est un élément de l'expression régulière ; il ne faut pas introduire d'espaces qui seraient pris comme des caractères constitutifs de l'expression.
Application ;
#!/usr/bin/python3
import re
textes = \"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,\\
Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\"
patron = \"\\\\b(?# début de mot)\\
\\w+(?:[.]\\w+)?(?# un ou deux mots séparés par un point)\\
@\\
\\w+(?:[.]\\w+)*(?# un, ou plusieurs mots séparés par un point)\\
[.]\\
(?:fr|com)(?# le dernier étant soit fr soit com)\\
\\\\b(?# fin de mot)\"
print (patron,\"\\n\")
cpatron = re.compile(patron)
print (cpatron.findall(textes))
Ecrire et tester le code ci-dessous.
Quel est l'intérêt de mettre des commentaires dans les expressions régulières?
* On a ici combiné les deux méthodes : le gain de lisibilité est réel mais ce n'est pas encore le grand confort : il manque une aération par des espaces par exemple.
D'autre part, la méthode de l'antislash terminal peut introduire des erreurs peu visibles si on ajoute malencontreusement des blancs.
","title":"Le commentaire en ligne"},{"edit":"
Ecrire ici les résultats.
"}],[{"text":"
La directive VERBOSE a comme effet d'occulter tous les blancs (espaces, tabulations, fin de ligne...) de la chaîne de saisie.
De plus, l'introduction dans une ligne du symbole # a le même effet qu'en Python : il supprime la fin de ligne physique à partir du hashtag (dièse pour les vieux). Encore faut-il qu'il y ait fin de ligne!
La triple quote ( \"\"\" ) s'impose alors ;
- la chaîne délimitée ainsi est prise littéralement, avec ses fins de lignes.
On dispose de l'aération souhaitée, mais au prix d'une perte des blancs et du dièse. Il suffit en général d'utiliser le joker \\s pour résoudre le problème, ou alors de protéger le caractère dans une classe ou avec un antislash.
Application :
#!/usr/bin/python3
import re
textes = \"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,\\
Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\"
patron = \"\"\"
\\\\b # début de mot)
\\w+(?:[.]\\w+)? # un ou deux mots séparés par un point
@\\
\\w+(?:[.]\\w+)* # un, ou plusieurs mots mots séparés par un point
[.]\\
(?:fr|com) # le dernier étant soit fr soit com
\\\\b # fin de mot
\"\"\"
print (patron,\"\\n\")
cpatron = re.compile(patron, re.VERBOSE)
print (cpatron.findall(textes))
Ecrire et tester le code ci-dessous.
Justifier le résultat.
","title":"La directive VERBOSE."},{"edit":"
Ecrire ici vos réponses.
"}],[{"text":"
#!/usr/bin/python3
import re
textes = \"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser., Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser., Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,\\
Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser., Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser., Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\"
cpatron = re.compile(
\"\\\\b\"# début de mot
\"\\w+\"# suite de caractères alphamériques
\"(?:[.]\\w+)?\"# 0 ou 1 point et suite de caractères alphanumériques
\"@\"#
\"\\w+\"# suite de caractères alphamériques
\"(?:[.]\\w+)*\"# x point et suite de caractères alphanumériques
\"[.](?:fr|com)\"# suffixe en fr ou en com
\"\\\\b\"# fin de mot
)
print (cpatron.findall(textes))
On joue ici triplement sur l'implicite : dans une parenthèse, les nouvelles lignes ne sont pas prises en compte ; les commentaires sont ignorés à l'analyse lexicale ; deux chaînes littérales juxtaposées sont concaténées... Cela fonctionne, mais c'est dangereux !
Ecrire et tester le code.
","title":"Jouer sur l'implicite."},{"edit":""}],[{"text":"
Il existe un opérateur de chaîne, r, qui permet de court-circuiter l'analyse lexicale de Python. Il suffit alors de fournir comme patron la chaîne d'entrée de l'analyseur du moteur d'évaluation des expressions régulières.
On y gagne quelques antislashes
#!/usr/bin/python3
import re
textes = \"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,\\
Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\"
Conclure sur les différentes manières d'écrire une expression régulière.
","title":"L'opérateur de chaîne r."},{"edit":"
Ecrire ici les résultats.
"}],[{"text":"
Jusque là, on n'a rencontré que des expressions régulières \"additives\". C'est à dire, tout l'ensemble décrit doit correspondre à une sous-chaîne pour que la correspondance soit reconnue.
On peut avoir besoin de chercher une correspondance avec l'une ou l'autre de deux expressions régulières.
Dans ce cas, on les sépare par le symbole | (barre verticale, le Alt gr 6 du clavier / valeur ASCII 124).
On écrit A|B avec A et B comme expressions régulières.
Plusieurs questions se posent avec le ou logique :
- les deux conditions peuvent-elles être satisfaites en même temps ? Cela n'est pas interdit. - dans quel ordre se fait l'évaluation des expressions régulières ? De gauche à droite.
- lorsque l'évaluation de la première expression est satisfaite, la seconde est-elle testée ? La réponse est non. Cette absence de gourmandise peut parfois causer des surprises, puisque la seconde évaluation aurait pu apporter une solution plus \"complète\".
- où s'arrête l'analyse lorsqu'une correspondance est détectée ? l'analyse s'arrête sur le premier caractère non reconnu (ou la fin de chaîne).
- peut-on avoir cet opérateur en série (succession de ou logiques) ou en cascade (insertion d'une expression avec un ou plusieurs ou dans une expression complexe. La réponse est oui. Dans la série, la règle \"de gauche à droite\" s'applique.
note. le caractère | doit être protégé \\| ou constituer un jeu de caractère [|] s'il est littéral 5.2. un exemple sans parenthésage.
Application : On dispose d'un texte comportant des noms de communes. On veut en extraire la liste des noms qui comportent le mot ville (ou Ville) en tant que chaîne terminale, c'est-à-dire suivi par un trait d'union ou en fin de nom. Par exemple Villers n'est pas admis ; mais Maville, Pont-Ville, Hauteville-Cajun, Ville-Sur-Cher le sont.
- le point ne peut être un \\n. En faisant .* on s'arrête automatiquement en fin de ligne si on l'atteint. Par contre dans la seconde partie de l'alternative, le $ est nécessaire.
- dans le cas de Amaville-sur-Ville, seule la première expression est évaluée.
","title":"Expression avec un ou logique"},{"edit":"
Ecrire ici les résultats.
"}],[{"text":"
Exemple 1:
Rechercher dans une liste Python des adresses mail correctes qui ont pour extension terminale .fr ou .com . On rejètera les adresses incorrectes et celles qui n'ont pas la bonne extension.
#!/usr/bin/python3
import re
textes = [\"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\",\"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\",\"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\",
\"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\", \"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\" ]
textes = \"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,\\
Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\"
","title":"Exemples avec parenthésage. "},{"edit":"
Ecrire ici les résultats.
"}],[{"text":"
On peut insérer les directives dans le patron.
La syntaxe est la suivante :
(?iLmsuxa)
où une ou plusieurs lettres peuvent être absentes :
i pour IGNORECASE,
L pour LOCALE,
m pour MULTILINE,
s pour DOTALL,
u pour UNICODE,
x pour VERBOSE,
a pour ASCII.
Étant donné le processus que nous avons recommandé, l'usage en est rare.
Par contre, il n'en est pas de même si on avait choisi une autre méthodologie, par exemple celle des fonctions du module re (fonction re.search(), re.findall() etc).
","title":"Les directives insérées dans les expressions"},{"edit":"
"}],[{"text":"
On a déjà rencontré un mode de groupement en utilisant le \"parenthésage\".
Il existe un second système appelé groupe, qui a, en plus des propriétés du parenthésage, des propriétés très spécifiques.
On prendra garde que le \"groupe\" n'est pas l'équivalent du parenthésage mathématique.
","title":"Les groupes"},{"edit":"
"}],[{"text":"
Un patron est un groupe. En effet, c'est le groupe de niveau le plus bas, le niveau 0.
Si on veut définir des sous-groupes, il suffit de parenthéser des sous-expressions régulières constituant l'expression globale.
Les groupes sont numérotés :
- 0 pour le patron;
- 1, 2,... pour les sous-groupes.
La numérotation se fait de gauche à droite, et pour un groupe, elle est égale au nombre total de parenthèses ouvrantes qui le précède.
On récupère les groupes en analysant l'objet SRE_Pattern retourné par search() .
Quant à la méthode findall() elle retourne une liste groupes ou de tuples (n-uplets) de groupes (voir exemple ci-dessous).
note. Les littéraux ( et ) doivent être protégés. Mais attention ! Le point d'interrogation ne peut suivre la parenthèse ouvrante ; il faut aussi le protéger :
(? se code \\(\\?.
Les opérateurs comme *, +, ?, |, qui s'appliquent à un caractère ou une expression paranthésée s'appliquent à un groupe.
","title":"Groupement de sous-expressions régulières"},{"edit":"
On reprend l'exemple précédent, mais en transformant chaque alternative en groupe. La méthode findall() continue à donner l'évaluation des deux groupes.
Cependant, si c'est le premier groupe qui est reconnu, le second n'est pas évalué (absence de gourmandise) : il est vide ; si c'est le second qui est reconnu, le premier est vide parce que non reconnu.
Les opérateurs vus dans la séquence précédente permettent de répondre aux problèmes liés à la répétition d'un caractère. Le seul joker dont on dispose est le point (sous deux acceptions, avec ou sans fin de ligne). La première extension souhaitable est de diversifier les jokers.
","title":"Introduction"},{"edit":"
"}],[{"text":"
Les. jeux de caractères définis ou classes.
Au lieu de dire \"tout caractère\" comme avec le joker \"point\", on peut définir en extension un jeu de caractères. La syntaxe est simple :
[caractères du jeu]
Les caractères sont écrits en suivant, dans une suite sans espacements :
[abcABC$*+]
est le jeu (la classe) des 9 caractères a,b,c,A,B,C,$,*,+
Il n'est pas utile d'échapper les caractères litigieux des expressions régulières comme *, +, . etc.
C'est une bonne méthode de protection : on écrit [*] au lieu de \\*
Il existe une forme abrégée pour les séquences :
premier et dernier caractère séparés par un trait
d'union : [a-z] pour une minuscule, [A-Z] pour une majuscule, [0-9] pour un chiffre.
C'est ainsi que [a-zA-Z] équivaut à \"toute lettre ASCII\".
Le jeu [À-ÿ] est tout à fait valide.
Une définition de jeu peut être définie par exclusion :
il suffit de commencer par ^.
Par exemple :
- le jeu [^5] définit tout caractère sauf 5.
- [^0-9] : tout caractère sauf un chiffre.
Pour éviter certaines protections lourdes, on peut définir des jeux à un caractère :
[*], ou [+], ou [\\\\] ; cela remplace avantageusement \\* \\+ ou \\\\\\\\
Remarque : Le caractère ^ doit être protégé lorsque son utilisation est littérale, soit en début d'expression, soit en début de jeu de caractère : [\\^abcd]; [\\^]. On ne peut pas écrire [^].
","title":"Diversifier les jokers et marqueurs"},{"edit":"
"}],[{"text":"
Certaines classes sont prédéfinies, ainsi que certains marqueurs :
Jeu prédéfini
Signification
\\A
trouver uniquement au début de la chaîne. Ressemble à ^ mais n'est pas affecté par la directive MULTILINE.
\\b
\\b est réservé en python (c'est le backspace) ; il faut donc écrire \\\\b pour utiliser dans une chaîne Python. Le caractère qui suit est en début ou fin de mot.
\\B
le caractère qui suit n'est ni en début de mot, ni en fin de mot.
\\d
équivalent de [0-9]
\\D
tout caractère sauf un chiffre
\\s
équivaut à [ \\b\\t\\n\\r\\f\\v], espace, backspace, tabulation, fin de ligne(LF), début de ligne (CR), à la ligne (FF), tabulation verticale. On désigne parfois ces caractères comme des blancs.
\\S
tout caractère sauf ceux de \\s
\\w
équivalent à [a-zA-Z0-9_], caractères alphanumériques. Peut être affecté par la directive LOCALE.
\\W
tout caractère non alphanumérique
\\Z
trouve uniquement en fin de la chaîne. Ressemble à $ mais est insensible à la directive MULTILINE.
","title":"Classes et marqueurs usuels prédéfinis"},{"edit":"
"}],[{"text":"
En calcul numérique, on utilise les parenthèses pour hiérarchiser les opérations. Il en est de même pour les expressions régulières.
On peut parenthéser une sous-expression régulière et lui appliquer les opérateurs d'itération vus pour les caractères.
ATTENTION : Le parenthésage a une syntaxe peu intuitive et déroutante :
Problème : examiner si une chaîne est une adresse mail valide.
Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.
Une adresse mail comporte une ou deux chaînes alphanumériques ; dans ce second cas, un point les sépare.
Le caractère @ suit. La seconde partie est constituée d'une suite d'au moins deux chaînes alphanumériques séparées par un point.
import re
textes1 = [Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.', \"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\",
\"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\",'zorlubfree.fr']
textes2 = ['zorlub@free', \"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\",
\"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.. fr\",\"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser. \"]
g_patron = \"^\\w+(?:[.]\\w+)?\"# partie gauche
d_patron = \"\\w+(?:[.]\\w+)+$ \"# partie droite
cpatron = re.compile(g_patron+\"@\"+d_patron)
#teste les 2 listes de mails
for x in textes1 + textes2:
res = cpatron.search(x)
if res:
print (x, \"est correct\")
else:
print (x, \"n'est pas une adresse valide\")
Ecrire et tester le code ci-dessous.
Justifier la forme de l'expression régulière.
","title":"Application"},{"edit":"
Ecrire les résultats ici.
"}],[{"text":"
Deux analyses en pipeline.
Que se passe-t-il entre la lecture du source d'une expression régulière et l'édition d'un patron compilé qui est utilisé par les méthodes search(), match(), findall(), sub() et split()?
patron = chaîne_source
cpatron = compile(patron)
Il y a deux étapes au niveau lexical : l'analyseur de chaîne Python lit la chaîne source et la traite :
il en sort une chaîne interne dans le format de stockage de Python. C'est à ce niveau que sont traités les caractères spéciaux comme le backslash (\\b) et la fin de ligne (\\n).
Puis l'analyseur lexical de la machine d'analyse des expressions régulières prend le relai et isole les unités lexicales que comprend l'analyseur d'E.R.. Les jokers, les marqueurs, les expressions sont de telles unités lexicales.
On a figuré deux éléments qui relèvent de l'analyse syntaxique (classe, chaîne).
","title":"La double analyse lexicale"},{"edit":"
"}],[{"text":"
Lorsque Python réalise l'analyse lexicale d'une chaîne littérale pour en créer la représentation interne, il lit la représentation littérale (flot d'entrée) de gauche à droite pour en dégager les unités lexicales, qui seront ensuite codées comme un caractère (flot de sortie) :
- l'antislash en fin de ligne est ignoré (chaînes sur plusieurs lignes). Le changement de ligne qui suit est ignoré également.
Un analyseur lexical prend un flot de caractères sur son entrée standard, isole les unités lexicales, et envoie un flot d'unités lexicales sur sa sortie standard. Une unité lexicale peut être un identificateur, un mot réservé du langage, un signe (+ - * / ! etc), un délimiteur (parenthèse, accolade, crochet, /*, */ etc), c'est-à-dire toute unité pertinente pour l'analyse syntaxique.
- les unités lexicales tiennent en général sur un seul caractère ; c'est le cas des caractères alphanumériques ou des caractères accentués ou de la ponctuation par exemple.
- certaines unités ont besoin de deux caractères dans la chaîne littérale : par exemple la fin de ligne est notée \\n, le backspace \\b, la tabulation \\t. Ces couples correspondent à une seule unité lexicale (un caractère dans la chaîne interne).
- certaines peuvent tenir sur un ou deux caractères sans poser de difficulté : \\\" et \\'. En effet, les caractères \" et ' étant des délimiteurs, leur échappement par l'antislash permet de les considérer comme des littéraux. Ainsi si on pose :
maChaine ='papa \"Noël\" s\\'est envolé'
taChaine = 'papa \\\"Noël\\\" s\\'est envolé'
saChaine ='papa \\\"Noël\" s\\'est envolé'
print (maChaine==taChaine,maChaine==saChaine)
on peut vérifier que les trois chaînes sont similaires.
- la difficulté apparaît lorsque l'on utilise l'antislash. L'antislash peut s'échapper lui-même : c'est sans ambigüité ; même chose pour \" et '. Mais qu'en est-il s'il précède un caractère qui ne peut être échappé. Comme par exemple un espace,les caractères c, d, w, ...
L'antislash est alors considéré comme littéral !
exemple :
print(\"\\c\\d\\w\") donne : \\c\\d\\w
- enfin, plus délicat encore certaines séquences antislashées introduisent des séquences spécifiques, comme par exemple des séquences unicodes ou numériques (cas de \\u \\U \\x \\N)
Voici ce que dit la documentation officielle :
Escape Sequence
Meaning
\\newline
Backslash and newline ignored
\\\\
Backslash (\\)
\\'
Single quote (')
\\\"
Double quote (\")
\\a
ASCII Bell (BEL)
\\b
ASCII Backspace (BS)
\\f
ASCII Formfeed (FF)
\\n
ASCII Linefeed (LF)
\\r
ASCII Carriage Return (CR)
\\t
ASCII Horizontal Tab (TAB)
\\v
ASCII Vertical Tab (VT)
\\ooo
Character with octal value ooo
\\xhh
Character with hex value hh
Escape sequences only recognized in string literals are:
Escape Sequence
Meaning
\\N{name}
Character named name in the Unicode database
\\uxxxx
Character with 16-bit hex value xxxx
\\Uxxxxxxxx
Character with 32-bit hex value xxxxxxxx
Applications :
La chaîne \"\\123\" donne le caractère de code octal 123 en Unicode, soit S (code 64+2x8+3 = 83) :
print(ord(\"\\123\"), \"123\")
La chaîne \"\\u00b5\" donne le μ de code 181 :
print(ord(\"\\u00b5\"), \"\\u00b5\")
Tester et verifier les résultats des instructions ci-dessus.
Chaque caractère unicode a un nom (importer le module unicode):
D'où la liste des caractères alphanumériques pour lesquelles l'antislash n'est pas un littéral
On insiste bien sur le fait que l'analyse lexicale de Python s'applique à tout ce qui se trouve sur le flot d'entrée de l'analyseur, texte comme patron.
","title":"L'échappement dans les chaînes en Python."},{"edit":"
Ecrire les résultats ici.
"}],[{"text":"
Lors de la compilation, c'est la chaîne interne de Python qui est examinée par l'analyseur lexical du moteur d'analyse des expressions régulières.
Il y a alors le second niveau d'analyse, qui lui aussi utilise l'antislash pour caractère d'échappement ! Cela ne pose pas de problème avec ^, ( , ) , { , }, w, W, B, 8, 9, $. Il y en a un avec les caractères particuliers qu'il faut échapper à l'aide d'un \\\\ lors de la première analyse lexicale. Il faut prêter une attention particulière aux caractères b, 0, 1, 2, 3, 4, 5, 6, 7.
Quand à l'antislash, comme il est doublement caractère d'échappement, pour l'utiliser comme littéral, il vaut mieux l'échapper pour Python, puis pour l'analyse re, ce qui fait quatre antislash ! \\\\\\\\
","title":" L'échappement des expressions régulières"},{"edit":"
Ecrire ici vos résultats.
"}],[{"text":"
Le problème : les expressions régulières sont particulièrement indigestes. Parmi les faits qui
concourent à une lecture difficile on peut citer :
- l'absence de caractères d'aération, ce que l'on appelle parfois \"les blancs\" : espaces, tabulation, saut de ligne ;
- l'absence de commentaires explicatifs insérés dans l'expression ;
- les difficultés liées au fait que l'on cumule deux niveaux d'analyse : l'analyse lexicale de Python qui donne une première représentation de l'expression, puis l'analyse lexicale du moteur d'expressions régulières. La multiplication des échappements est liée à cet aspect de la question.
Cette difficulté de lecture peut être en partie levée par l'utilisation de techniques appartenant à l'un ou l'autre des analyseurs lexicaux.
Remarque : Dans les exemples qui suivent, la signification des expressions régulières n'a pas à être examinée. Ces exemples illustrent l'aération du patron.
- Caractères particuliers pour l'échappement N U u x 01 2 3 4 5 6 7 a b f n r v
","title":"Donner de l'air aux expressions régulières"},{"edit":"","css":"","js":""}],[{"text":"
En Python, on peut saisir une chaîne sur plusieurs lignes physiques ; il suffit de terminer chaque élément significatif du texte par un antislash suivi d'un passage à la ligne. Attention, après l'antislash il ne doit rien y avoir !
Il y a alors concaténation des segments de texte à l'analyse lexicale.
Application :
import re
textes = \"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,\\
Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\"
patron = \"\\\\b\\
\\w+\\
(?:[.]\\w+)?\\
@\\
\\w+\\
(?:[.]\\w+)*\\
[.](?:fr|com)\\
\\\\b\"
print(patron,\"\\n\")
cpatron = re.compile(patron)
print (cpatron.findall(textes))
Ecrire et tester le code ci-dessus.
Justifier la mise en forme du code.
","title":"La saisie multiligne des chaînes"},{"edit":"
Ecrire ici le résultat.
"}],[{"text":"
La syntaxe est (?# texte )
Le texte est un commentaire ; il est ignoré.
On doit prendre garde à ce que le commentaire en ligne est un élément de l'expression régulière ; il ne faut pas introduire d'espaces qui seraient pris comme des caractères constitutifs de l'expression.
Application ;
#!/usr/bin/python3
import re
textes = \"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,\\
Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\"
patron = \"\\\\b(?# début de mot)\\
\\w+(?:[.]\\w+)?(?# un ou deux mots séparés par un point)\\
@\\
\\w+(?:[.]\\w+)*(?# un, ou plusieurs mots séparés par un point)\\
[.]\\
(?:fr|com)(?# le dernier étant soit fr soit com)\\
\\\\b(?# fin de mot)\"
print (patron,\"\\n\")
cpatron = re.compile(patron)
print (cpatron.findall(textes))
Ecrire et tester le code ci-dessous.
Quel est l'intérêt de mettre des commentaires dans les expressions régulières?
* On a ici combiné les deux méthodes : le gain de lisibilité est réel mais ce n'est pas encore le grand confort : il manque une aération par des espaces par exemple.
D'autre part, la méthode de l'antislash terminal peut introduire des erreurs peu visibles si on ajoute malencontreusement des blancs.
","title":"Le commentaire en ligne"},{"edit":"
Ecrire ici les résultats.
"}],[{"text":"
La directive VERBOSE a comme effet d'occulter tous les blancs (espaces, tabulations, fin de ligne...) de la chaîne de saisie.
De plus, l'introduction dans une ligne du symbole # a le même effet qu'en Python : il supprime la fin de ligne physique à partir du hashtag (dièse pour les vieux). Encore faut-il qu'il y ait fin de ligne!
La triple quote ( \"\"\" ) s'impose alors ;
- la chaîne délimitée ainsi est prise littéralement, avec ses fins de lignes.
On dispose de l'aération souhaitée, mais au prix d'une perte des blancs et du dièse. Il suffit en général d'utiliser le joker \\s pour résoudre le problème, ou alors de protéger le caractère dans une classe ou avec un antislash.
Application :
#!/usr/bin/python3
import re
textes = \"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,\\
Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\"
patron = \"\"\"
\\\\b # début de mot)
\\w+(?:[.]\\w+)? # un ou deux mots séparés par un point
@\\
\\w+(?:[.]\\w+)* # un, ou plusieurs mots mots séparés par un point
[.]\\
(?:fr|com) # le dernier étant soit fr soit com
\\\\b # fin de mot
\"\"\"
print (patron,\"\\n\")
cpatron = re.compile(patron, re.VERBOSE)
print (cpatron.findall(textes))
Ecrire et tester le code ci-dessous.
Justifier le résultat.
","title":"La directive VERBOSE."},{"edit":"
Ecrire ici vos réponses.
"}],[{"text":"
#!/usr/bin/python3
import re
textes = \"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser., Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser., Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,\\
Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser., Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser., Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\"
cpatron = re.compile(
\"\\\\b\"# début de mot
\"\\w+\"# suite de caractères alphamériques
\"(?:[.]\\w+)?\"# 0 ou 1 point et suite de caractères alphanumériques
\"@\"#
\"\\w+\"# suite de caractères alphamériques
\"(?:[.]\\w+)*\"# x point et suite de caractères alphanumériques
\"[.](?:fr|com)\"# suffixe en fr ou en com
\"\\\\b\"# fin de mot
)
print (cpatron.findall(textes))
On joue ici triplement sur l'implicite : dans une parenthèse, les nouvelles lignes ne sont pas prises en compte ; les commentaires sont ignorés à l'analyse lexicale ; deux chaînes littérales juxtaposées sont concaténées... Cela fonctionne, mais c'est dangereux !
Ecrire et tester le code.
","title":"Jouer sur l'implicite."},{"edit":""}],[{"text":"
Il existe un opérateur de chaîne, r, qui permet de court-circuiter l'analyse lexicale de Python. Il suffit alors de fournir comme patron la chaîne d'entrée de l'analyseur du moteur d'évaluation des expressions régulières.
On y gagne quelques antislashes
#!/usr/bin/python3
import re
textes = \"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,\\
Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\"
Conclure sur les différentes manières d'écrire une expression régulière.
","title":"L'opérateur de chaîne r."},{"edit":"
Ecrire ici les résultats.
"}],[{"text":"
Jusque là, on n'a rencontré que des expressions régulières \"additives\". C'est à dire, tout l'ensemble décrit doit correspondre à une sous-chaîne pour que la correspondance soit reconnue.
On peut avoir besoin de chercher une correspondance avec l'une ou l'autre de deux expressions régulières.
Dans ce cas, on les sépare par le symbole | (barre verticale, le Alt gr 6 du clavier / valeur ASCII 124).
On écrit A|B avec A et B comme expressions régulières.
Plusieurs questions se posent avec le ou logique :
- les deux conditions peuvent-elles être satisfaites en même temps ? Cela n'est pas interdit. - dans quel ordre se fait l'évaluation des expressions régulières ? De gauche à droite.
- lorsque l'évaluation de la première expression est satisfaite, la seconde est-elle testée ? La réponse est non. Cette absence de gourmandise peut parfois causer des surprises, puisque la seconde évaluation aurait pu apporter une solution plus \"complète\".
- où s'arrête l'analyse lorsqu'une correspondance est détectée ? l'analyse s'arrête sur le premier caractère non reconnu (ou la fin de chaîne).
- peut-on avoir cet opérateur en série (succession de ou logiques) ou en cascade (insertion d'une expression avec un ou plusieurs ou dans une expression complexe. La réponse est oui. Dans la série, la règle \"de gauche à droite\" s'applique.
note. le caractère | doit être protégé \\| ou constituer un jeu de caractère [|] s'il est littéral 5.2. un exemple sans parenthésage.
Application : On dispose d'un texte comportant des noms de communes. On veut en extraire la liste des noms qui comportent le mot ville (ou Ville) en tant que chaîne terminale, c'est-à-dire suivi par un trait d'union ou en fin de nom. Par exemple Villers n'est pas admis ; mais Maville, Pont-Ville, Hauteville-Cajun, Ville-Sur-Cher le sont.
- le point ne peut être un \\n. En faisant .* on s'arrête automatiquement en fin de ligne si on l'atteint. Par contre dans la seconde partie de l'alternative, le $ est nécessaire.
- dans le cas de Amaville-sur-Ville, seule la première expression est évaluée.
","title":"Expression avec un ou logique"},{"edit":"
Ecrire ici les résultats.
"}],[{"text":"
Exemple 1:
Rechercher dans une liste Python des adresses mail correctes qui ont pour extension terminale .fr ou .com . On rejètera les adresses incorrectes et celles qui n'ont pas la bonne extension.
#!/usr/bin/python3
import re
textes = [\"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\",\"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\",\"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\",
\"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\", \"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\" ]
textes = \"Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,\\
Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.,Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.\"
","title":"Exemples avec parenthésage. "},{"edit":"
Ecrire ici les résultats.
"}],[{"text":"
On peut insérer les directives dans le patron.
La syntaxe est la suivante :
(?iLmsuxa)
où une ou plusieurs lettres peuvent être absentes :
i pour IGNORECASE,
L pour LOCALE,
m pour MULTILINE,
s pour DOTALL,
u pour UNICODE,
x pour VERBOSE,
a pour ASCII.
Étant donné le processus que nous avons recommandé, l'usage en est rare.
Par contre, il n'en est pas de même si on avait choisi une autre méthodologie, par exemple celle des fonctions du module re (fonction re.search(), re.findall() etc).
","title":"Les directives insérées dans les expressions"},{"edit":"
"}],[{"text":"
On a déjà rencontré un mode de groupement en utilisant le \"parenthésage\".
Il existe un second système appelé groupe, qui a, en plus des propriétés du parenthésage, des propriétés très spécifiques.
On prendra garde que le \"groupe\" n'est pas l'équivalent du parenthésage mathématique.
","title":"Les groupes"},{"edit":"
"}],[{"text":"
Un patron est un groupe. En effet, c'est le groupe de niveau le plus bas, le niveau 0.
Si on veut définir des sous-groupes, il suffit de parenthéser des sous-expressions régulières constituant l'expression globale.
Les groupes sont numérotés :
- 0 pour le patron;
- 1, 2,... pour les sous-groupes.
La numérotation se fait de gauche à droite, et pour un groupe, elle est égale au nombre total de parenthèses ouvrantes qui le précède.
On récupère les groupes en analysant l'objet SRE_Pattern retourné par search() .
Quant à la méthode findall() elle retourne une liste groupes ou de tuples (n-uplets) de groupes (voir exemple ci-dessous).
note. Les littéraux ( et ) doivent être protégés. Mais attention ! Le point d'interrogation ne peut suivre la parenthèse ouvrante ; il faut aussi le protéger :
(? se code \\(\\?.
Les opérateurs comme *, +, ?, |, qui s'appliquent à un caractère ou une expression paranthésée s'appliquent à un groupe.
","title":"Groupement de sous-expressions régulières"},{"edit":"
On reprend l'exemple précédent, mais en transformant chaque alternative en groupe. La méthode findall() continue à donner l'évaluation des deux groupes.
Cependant, si c'est le premier groupe qui est reconnu, le second n'est pas évalué (absence de gourmandise) : il est vide ; si c'est le second qui est reconnu, le premier est vide parce que non reconnu.
Quelles sont les différences pour les résultats affichés.
","title":"Exemples avec findall()."},{"edit":"
Ecrire ici les résultats.
"}],[{"text":"
La numérotation se fait de gauche à droite, et pour un groupe, elle est égale au nombre total de parenthèses ouvrantes qui le précède.
#!/usr/bin/python3
import re
texte = \" abcdefghijklmnopqrstuvwxyz \"
patron = \"abc(def(ghi)(jkl))(mno)pqr\"
cpatron = re.compile(patron)
res = cpatron.search(texte)
if res :
try:
for i inrange (99) : # maximum de 99 groupes
print (\"groupe\", i , \":\", res.group(i))
except:
pass
Ecrire et tester le code.
Justifier les résultats.
Attention : Si le patron comporte un ou logique la règle de numérotation continue à s'appliquer. Par exemple, le patron \"ab(c)d|xy(z)\" comporte deux groupes : numérotés 1 (c) et 2 (z).
","title":"Règle de numérotation des groupes"},{"edit":"
","title":"Nommer les groupes"},{"edit":" "}],[{"text":"
Lorsqu'un groupe est identifié à un segment de chaîne, la valeur de la sous-chaîne identifiée peut être \"capturée\", et utilisée dans l'expression régulière et dans la fonction de remplacement sub().
La valeur reconnue se désigne dans l'expression régulière par un antislash suivi de son numéro
(exemple : \\5 pour la chaîne du groupe 5) ou par la convention de nommage :
(?P=identificateur)
Mais l'antislash suivi d'un chiffre peut avoir une signification en Python, il faut donc doubler l'antislash dans la chaîne Python. Par ailleurs, cette notation devient ambiguë avec les valeurs au delà de 10.
Comment
est interprèté \\14 ? groupe 1 suivi de 4 ou groupe 14 ? Dans le patron le nombre à deux chiffres est correctement interprété comme \"groupe 14\" ; le groupe 1 suivi de 4 doit s'écrire par exemple \\\\1[4].
","title":"Capture des groupes."},{"edit":" "}],[{"text":"
Problème : trouver les mots d'un texte qui commencent et se terminent par la même lettre.
import re
texte = \"J'ai été en sursis et j'irai bien désormais\"
patron = \"\\\\b(\\w).*?\\\\1\\\\b\"
cpatron = re.compile(patron)
whileTrue :
print (texte)
res = cpatron.search(texte)
if res :
print (res.group(0))
texte = texte [res.end():]
else: break
On a figuré le groupe et la chaîne dont l'identification relève de l'analyse syntaxique.
","title":"Exemple d'usage du numéro"},{"edit":" "}],[{"text":"
#!/usr/bin/python3
import re
texte = \"J'ai été en sursis et j'irai bien désormais\"
","title":"Usage de la convention de nommage. exemple"},{"edit":" "}],[{"text":"
On peut utiliser les éléments capturés dans la chaîne de remplacement.
Les conventions de nommage sont alors :
\\g<identificateur>
\\g<numéro>
Les symboles < et > ne sont pas indispensables si le numéro n'a qu'un chiffre ; mais cette facilité est à éviter à cause de l'ambiguïté qui naît avec les valeurs à deux chiffres.
Voici un problème d'illustration : on dispose d'un texte html, et on veut remplacer l'expression align=center par une autre chaîne, mais uniquement dans les balises de bloc de texte, c'est-à-dire commençant par h0,h1 ...h9 ou p.
De plus, on veut éliminer tout le reste des attributs de ces balises.
import re
texte = \"\"\"<h1 name=\"titre\"
align=CENTER>align=center</h1>
<img src=\"kw154.png\" align = center>
<p align = center id=\"zazozi\" >wawawa</p>
<h2 align= center>fin de texte</h2>\"\"\"
print(\"La page html :\", texte)
patron = \"\"\"
(<h\\d|<p) # balise commençant par <h avec chiffre ou <p
# les deux groupes sont utilisés dans la chaîne de remplacement.
res = cpatron.sub('\\g<1> style=\\'align:center;\\' \\g<2>', texte)
print(res)
Ecrire et tester le code ci-dessous.
Justifier le résultat.
","title":"La fonction de remplacement sub() avec capture"},{"edit":" "}],[{"text":"
Le problème :
Supposons que l'on dispose de l'expression régulière patron mais que l'on veuille chercher une correspondance conditionnelle : seulement si l'expression à trouver est \"suivie\" (ou n'est pas suivie) d'une expression trouvée avec une autre expression régulière hpatron.
Par exemple, on cherche la chaîne \"Isaac\" suivie par \"Newton\" ou \"Asimov\". Ou le contraire. Évidemment, on peut compliquer un peu.
Une telle recherche s'appelle un lookahead. Sa caractéristique essentielle est qu'elle ne consomme que la chaîne recherchée, pas la chaîne conditionnelle.
","title":"Lookahead positif ou négatif"},{"edit":" "}],[{"text":"
Lookahead postposé
#!/usr/bin/python3
import re
texte = \"isaac jacob, Isaac Newton, Isaac Asimov,\\
isaac isaac\\n, isaac Isaac\"
print(\"le texte :\", texte)
patron =\"Isaac\\s(?=Asimov|Newton)\"
cpatron = re.compile(patron, re.IGNORECASE)
print (cpatron.findall(texte))
patron =\"Isaac(?:\\s|$)(?!Asimov|Newton)\"
cpatron = re.compile(patron, re.IGNORECASE)
print (cpatron.findall(texte))
Ecrire et tester le code.
Justifier les résultats.
Remarques :
- \\s pour un blanc (espace, fin de ligne).
- on voit bien sur le second cas qu'il n'y a pas consommation du lookahead.
","title":"Exemple :"},{"edit":" "}],[{"text":"
lookahead préposé. exemple 2 :
#!/usr/bin/python3
import re
texte = \"isaac jacob, IsaacNewton, Isaac Asimov, bellisaac\"
patron =\"(?=\\\\bisa\\w*\\\\b)isaac\"
cpatron = re.compile(patron, re.IGNORECASE)
print (cpatron.findall(texte))
Ecrire et tester le code ci-dessus.
Quelle est la différence avec l'exemple précédent.
Remarque :
e patron du lookahead est d'abord recherché ; s'il est trouvé, la recherche de la seconde partie du patron se fait à partir du premier élément trouvé, qui est ici un début de mot. On dit qu'il y a chevauchement.
","title":"Exemple avec lookahead préposé"},{"edit":" "}],[{"text":"
Une recherche de correspondance avec comme condition de suivre (ou non) une correspondance définie par une autre expression régulière est un lookbehind.
Le lookbehind consomme l'expression précédente, mais ne la retourne pas. Il n'y a pas de chevauchement avec le lookbehind, car la chaîne conditionnelle est avant la chaîne recherché.
Restriction :
- l'expression qui sert de condition doit avoir une longueur préfixée;
- on ne peut avoir de .* ou \\w* ;
- on peut avoir toto|titi.
Sinon, Il y a erreur à la compilation.
La syntaxe est la suivante:
(?<=expression lookbehind recherchée)
(?<!expression lookbehind rejetée)
","title":" Lookbehind positif ou négatif"},{"edit":" "}],[{"text":"
On a donc les 4 schémas possibles suivants quand on veut utiliser des conditions :
"},{"edit":" "}],[{"text":"Les expressions régulières sont des outils très puissants en informatique pour le traitement des chaînes de caractères. Nous avons vu qu'elles permettent donc de chercher, de trouver des correspondances, de découper, de remplacer à l'aide de motif et de patron dans des textes. Par ailleurs, vous pourrez les utiliser dans d'autre langage C, javascript, php, ...
En poursuivant votre navigation sur mon site,
vous acceptez l’utilisation des Cookies et autres traceurs
pour réaliser des statistiques de visites et enregistrer
sur votre machine vos activités pédagogiques.En savoir plus.