{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# Tech - expressions r\u00e9guli\u00e8res\n", "\n", "Les [expressions r\u00e9guli\u00e8res](https://fr.wikipedia.org/wiki/Expression_r%C3%A9guli%C3%A8re) sont utilis\u00e9es pour rechercher des motifs dans un texte tel que des mots, des dates, des nombres..."]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [{"data": {"text/html": ["
run previous cell, wait for 2 seconds
\n", ""], "text/plain": [""]}, "execution_count": 2, "metadata": {}, "output_type": "execute_result"}], "source": ["from jyquickhelper import add_notebook_menu\n", "add_notebook_menu()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Enonc\u00e9\n", "\n", "Le texte suivant est un po\u00e8me d'Arthur Rimbaud, Les Voyelles. On veut en extraire tous les mots."]}, {"cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": ["poeme = \"\"\"\n", "A noir, E blanc, I rouge, U vert, O bleu, voyelles,\n", "Je dirai quelque jour vos naissances latentes.\n", "A, noir corset velu des mouches \u00e9clatantes\n", "Qui bombillent autour des puanteurs cruelles,\n", "\n", "Golfe d'ombre; E, candeur des vapeurs et des tentes,\n", "Lance des glaciers fiers, rois blancs, frissons d'ombelles;\n", "I, pourpres, sang crach\u00e9, rire des l\u00e8vres belles\n", "Dans la col\u00e8re ou les ivresses p\u00e9nitentes;\n", "\n", "U, cycles, vibrements divins des mers virides,\n", "Paix des p\u00e2tis sem\u00e9s d'animaux, paix des rides\n", "Que l'alchimie imprime aux grands fronts studieux;\n", "\n", "O, supr\u00eame clairon plein de strideurs \u00e9tranges,\n", "Silences travers\u00e9s des Mondes et des Anges:\n", "\u2014O l'Om\u00e9ga, rayon violet de Ses Yeux!\n", "\"\"\""]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Exercice 1 : utiliser les expression r\u00e9guli\u00e8res pour extraire tous les mots\n", "\n", "En python, il faut utiliser le module [re](https://docs.python.org/3/library/re.html). Il faudra lire le paragraphe sur la syntaxe [Regular Expression Syntax](https://docs.python.org/3/library/re.html#regular-expression-syntax). Autres lectures : [Expressions r\u00e9guli\u00e8res](http://www.xavierdupre.fr/app/teachpyx/helpsphinx/c_regex/regex.html#a-quoi-ca-sert)."]}, {"cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": ["def extract_words(text):\n", " # utiliser les exrp\n", " pass\n", " \n", "extract_words(poeme)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Exercice 2 : utiliser les expression r\u00e9guli\u00e8res pour extraire tous les mots se terminant par la lettre s"]}, {"cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": []}, {"cell_type": "markdown", "metadata": {}, "source": ["### Exercice 3 : utiliser les expression r\u00e9guli\u00e8res pour remplacer tous les \"de\" en 2\n", "\n", "Les fonctions [finditer](https://docs.python.org/3/library/re.html#re.finditer) ou [sub](https://docs.python.org/3/library/re.html#re.sub) pourraient vous \u00eatre utile."]}, {"cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": []}, {"cell_type": "markdown", "metadata": {}, "source": ["### Exercice 4 : utiliser les expression r\u00e9guli\u00e8res pour extraire les lignes des rimes en `elle` ou `elles` ou `aile` ou `ailes`\n", "\n", "La fonction [finditer](https://docs.python.org/3/library/re.html#re.finditer) pourrait vous \u00eatre utile."]}, {"cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": []}, {"cell_type": "markdown", "metadata": {}, "source": ["## R\u00e9ponses"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Exercice 1 : utiliser les expression r\u00e9guli\u00e8res pour extraire tous les mots\n", "\n", "Les accents sont trait\u00e9s comme des lettres diff\u00e9rentes par les expressions r\u00e9guli\u00e8res. On peut soit les garder, soit les remplacer. Pour ce faire, on peut lire [What is the best way to remove accents (normalize) in a Python unicode string?](https://stackoverflow.com/questions/517923/what-is-the-best-way-to-remove-accents-normalize-in-a-python-unicode-string)."]}, {"cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [{"data": {"text/plain": ["'tetu'"]}, "execution_count": 8, "metadata": {}, "output_type": "execute_result"}], "source": ["import unicodedata\n", "\n", "def strip_accents(s):\n", " return ''.join(c for c in unicodedata.normalize('NFD', s)\n", " if unicodedata.category(c) != 'Mn')\n", "\n", "strip_accents('t\u00eatu')"]}, {"cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [{"data": {"text/plain": ["['A', 'noir', 'E', 'blanc', 'I']"]}, "execution_count": 9, "metadata": {}, "output_type": "execute_result"}], "source": ["import re\n", "\n", "def extract_words(text):\n", " text_sans_accent = strip_accents(text)\n", " return re.findall('[A-Za-z]+', text_sans_accent)\n", " \n", "mots = extract_words(poeme)\n", "mots[:5]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Exercice 2 : utiliser les expression r\u00e9guli\u00e8res pour extraire tous les mots se terminant par la lettre s\n", "\n", "On modifie le motif pour qu'il se termine par la lettre *s*. Le caract\u00e8re ``\\b`` est utilis\u00e9 pour signifier que cette lettre ne peut se trouver qu'\u00e0 la fin d'un mot."]}, {"cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [{"data": {"text/plain": ["['rouge', 'voyelles', 'Je', 'quelque', 'vos']"]}, "execution_count": 10, "metadata": {}, "output_type": "execute_result"}], "source": ["def extract_words_lettre(text, lettre='s'):\n", " text_sans_accent = strip_accents(text)\n", " return re.findall('[A-Za-z]+[' + lettre + ']\\\\b', \n", " text_sans_accent)\n", " \n", "mots = extract_words_lettre(poeme, 'se')\n", "mots[:5]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Exercice 3 : utiliser les expression r\u00e9guli\u00e8res pour remplacer tous les \"de\" en 2"]}, {"cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [{"data": {"text/plain": ["\"\\nA noir, E blanc, I rouge, U vert, O bleu, voyelles,\\nJe dirai quelque jour vos naissances latentes.\\nA, noir corset velu des mouches \u00e9clatantes\\nQui bombillent autour des puanteurs cruelles,\\n\\nGolfe d'ombre; E, candeur des vapeurs et des tentes,\\nLance des glaciers fiers, rois blancs, frissons d'ombelles;\\nI, pourpres, sang crach\u00e9, rire des l\u00e8vres belles\\nDans la col\u00e8re ou les ivresses p\u00e9nitentes;\\n\\nU, cycles, vibrements divins des mers virides,\\nPaix des p\u00e2tis sem\u00e9s d'animaux, paix des rides\\nQue l'alchimie imprime aux grands fronts studieux;\\n\\nO, supr\u00eame clairon plein 2 strideurs \u00e9tranges,\\nSilences travers\u00e9s des Mondes et des Anges:\\n\u2014O l'Om\u00e9ga, rayon violet 2 Ses Yeux!\\n\""]}, "execution_count": 11, "metadata": {}, "output_type": "execute_result"}], "source": ["re.sub(\"de\\\\b\", \"2\", poeme)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Exercice 4 : utiliser les expression r\u00e9guli\u00e8res pour extraire les lignes des rimes en `elle` ou `elles` ou `aile` ou `ailes`\n", "\n", "Un petit essai avant la solution."]}, {"cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [{"data": {"text/plain": ["[('elles', 'elle', '', 'elle'),\n", " ('elles', 'elle', '', 'elle'),\n", " ('elles', 'elle', '', 'elle'),\n", " ('elles', 'elle', '', 'elle')]"]}, "execution_count": 12, "metadata": {}, "output_type": "execute_result"}], "source": ["re.findall(\"(((aile)|(elle))s?\\\\b)\", poeme)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Un autre pour se convaincre..."]}, {"cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["46-51: elles\n", "182-187: elles\n", "296-301: elles\n", "346-351: elles\n"]}], "source": ["for m in re.finditer(\"(((aile)|(elle))s?\\\\b)\", poeme):\n", " print('%02d-%02d: %s' % (\n", " m.start(), m.end(), m.group(0)))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On m\u00e9lange. On d\u00e9coupe en ligne d'abord, et on applique le m\u00eame traitement sur chaque ligne."]}, {"cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": [" 2: 45-50/51: A noir, E blanc, I rouge, U vert, O bleu, voyelles,\n", " 5: 39-44/45: Qui bombillent autour des puanteurs cruelles,\n", " 8: 53-58/59: Lance des glaciers fiers, rois blancs, frissons d'ombelles;\n", " 9: 43-48/48: I, pourpres, sang crach\u00e9, rire des l\u00e8vres belles\n"]}], "source": ["for i, ligne in enumerate(poeme.split('\\n')):\n", " for m in re.finditer(\"(((aile)|(elle))s?\\\\b)\", ligne):\n", " print('% 2d: %02d-%02d/%02d: %s' % (\n", " i + 1, m.start(), m.end(), len(ligne), ligne))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Il ne resterait plus qu'\u00e0 v\u00e9rifier que la rime trouv\u00e9e, le motif, se trouve \u00e0 la fin de la ligne."]}, {"cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": []}], "metadata": {"kernelspec": {"display_name": "Python 3", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.2"}}, "nbformat": 4, "nbformat_minor": 2}