{"id":796,"date":"2017-08-30T17:42:11","date_gmt":"2017-08-30T15:42:11","guid":{"rendered":"http:\/\/perso.ens-lyon.fr\/lise.vaudor\/?p=796"},"modified":"2019-02-27T10:15:25","modified_gmt":"2019-02-27T09:15:25","slug":"strings-et-expressions-regulieres","status":"publish","type":"post","link":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/strings-et-expressions-regulieres\/","title":{"rendered":"Strings et expressions r\u00e9guli\u00e8res"},"content":{"rendered":"<p><img decoding=\"async\" src=\"..\/..\/lise.vaudor\/Rfigures\/Expressions_regulieres\/Lise_Vaudor_headband-1.png\" alt=\"\" \/><\/p>\n<h2>Les expressions r\u00e9guli\u00e8res, pour quoi faire?<\/h2>\n<p>Les expressions r\u00e9guli\u00e8res servent \u00e0 effectuer des recherches de <strong>patterns<\/strong> dans les strings en d\u00e9finissant les <strong>r\u00e8gles<\/strong> qui r\u00e9gissent ces patterns.<\/p>\n<p>Par exemple, si je cherche \u00e0 trouver le mot \u00ab\u00a0turlututu\u00a0\u00bb dans le string \u00ab\u00a0turlututu chapeau pointu\u00a0\u00bb, mon pattern est simplement \u00ab\u00a0turlututu\u00a0\u00bb. Si en revanche, je cherche \u00e0 trouver <strong>tous les mots d\u00e9butant par une majuscule qui ne correspondent pas \u00e0 un d\u00e9but de phrase<\/strong> dans \u00ab\u00a0For the Night is Dark and full of Terrors.\u00a0\u00bb mon pattern est d\u00e9fini par un ensemble de r\u00e8gles, qu&rsquo;il va falloir r\u00e9ussir \u00e0 expliquer (coder) dans un language intelligible par R, i.e. le langage des expressions r\u00e9guli\u00e8res.<\/p>\n<p>J&rsquo;ai longtemps \u00e9prouv\u00e9 un profond d\u00e9sespoir face aux expressions r\u00e9guli\u00e8res car elles me semblaient \u00e0 la fois profond\u00e9ment utiles et terriblement inaccessibles&#8230; Dans mon usage ordinaire de R, j&rsquo;arrive g\u00e9n\u00e9ralement \u00e0 m&rsquo;auto-former \u00e0 de nouvelles m\u00e9thodes en d\u00e9cortiquant des exemples d&rsquo;application disponibles en ligne (par exemple sur stackoverflow). Pour ce qui est des expressions r\u00e9guli\u00e8res, ces exemples me paraissaient totalement obscurs (et pour cause, une expression r\u00e9guli\u00e8re c&rsquo;est en quelque sorte un language \u00e0 part enti\u00e8re&#8230;). Par exemple, pour trouver un pattern qui correspond \u00e0 un mot qui commence par une majuscule mais qui n&rsquo;est pas plac\u00e9 en d\u00e9but de phrase, il faut lui indiquer l&rsquo;expression r\u00e9guli\u00e8re <code>\"(?&lt;![\\\\!\\\\.]\\\\s)\\\\b[:upper:][:lower:]+\\\\b\"<\/code>&#8230; WTF, n&rsquo;est-ce pas?<\/p>\n<p>Bon, heureusement, le package stringr est pass\u00e9 par l\u00e0 (cf mon pr\u00e9c\u00e9dent billet), et la lecture de <a href=\"http:\/\/stringr.tidyverse.org\/articles\/regular-expressions.html\">ce tutoriel<\/a> sur les expressions r\u00e9guli\u00e8res m&rsquo;a grandement aid\u00e9e \u00e0 y voir plus clair&#8230;<\/p>\n<p>Pour \u00ab\u00a0r\u00e9sumer\u00a0\u00bb les diff\u00e9rents aspects des expressions r\u00e9guli\u00e8res que j&rsquo;aborderai par la suite, j&rsquo;ai produit la figure suivante:<\/p>\n<p><img decoding=\"async\" src=\"..\/..\/lise.vaudor\/Rfigures\/Expressions_regulieres\/regexp.png\" alt=\"\" \/><\/p>\n<p>Notez qu&rsquo;il existe \u00e9galement une \u00ab\u00a0cheatsheet\u00a0\u00bb (moins rose mais plus exhaustive) <a href=\"https:\/\/www.rstudio.com\/wp-content\/uploads\/2016\/09\/RegExCheatsheet.pdf\">ici<\/a>&#8230;<\/p>\n<h2>Recherche de patterns avec stringr<\/h2>\n<p>Avant d&rsquo;entamer les choses s\u00e9rieuses (i.e. l&rsquo;\u00e9criture des expressions r\u00e9guli\u00e8res), une petite remarque.<\/p>\n<p>Pour montrer les r\u00e9sultats de la recherche de patterns, je vais utiliser <strong>les fonctions du package stringr<\/strong>, et notamment une fonction <code>str_view_all<\/code> qui permet de montrer la partie d&rsquo;un string correspondant \u00e0 un pattern.<\/p>\n<p>Ainsi, pour voir le r\u00e9sultat de recherche du pattern \u00ab\u00a0youpi\u00a0\u00bb dans les strings suivants, voici comment je peux proc\u00e9der:<\/p>\n<pre><code>s=c(\"wip wip\",\"youpi\",\"youpla\",\"boum\")\nstr_view_all(s,\"youpi\")\n\n## [1] \"wip wip\" \"{youpi}\" \"youpla\"  \"boum\"\n<\/code><\/pre>\n<p>(Quand on l&rsquo;utilise sous RStudio, la fonction str_view_all ouvre un widget html o\u00f9 la partie du string correspondant au pattern appara\u00eet sur un fond gris\u00e9. Ici, j&rsquo;ai un peu \u00ab\u00a0twist\u00e9\u00a0\u00bb cette fonction pour pouvoir en montrer les r\u00e9sultats sur mon blog, mais ne vous laissez pas perturber par ce d\u00e9tail!)<\/p>\n<h1>Classes de caract\u00e8res et groupes<\/h1>\n<p><img decoding=\"async\" src=\"..\/..\/lise.vaudor\/Rfigures\/Expressions_regulieres\/regexp_character_classes.png\" alt=\"\" \/><\/p>\n<p>On peut rechercher une <strong>classe de caract\u00e8res<\/strong> en utilisant la notation <code>[...]<\/code>.<\/p>\n<p>Par exemple, si je veux rechercher toutes les voyelles dans mon string:<\/p>\n<pre><code>str_view_all(\"youp la boum\",\n             \"[aeiou]\")\n\n## [1] \"y{o}{u}p l{a} b{o}{u}m\"\n<\/code><\/pre>\n<p>Remarquez bien la diff\u00e9rence:<\/p>\n<pre><code>str_view_all(c(\"A132\",\"f445\",\"e345\",\"C308\",\"M2244\",\"Z449\",\"E18\"),\n             \"[308]\")\n\n## [1] \"A1{3}2\"     \"f445\"       \"e{3}45\"     \"C{3}{0}{8}\" \"M2244\"      \"Z449\"       \"E1{8}\"\n\nstr_view_all(c(\"A132\",\"f445\",\"e345\",\"C308\",\"M2244\",\"Z449\",\"E18\"),\n             \"308\")\n\n## [1] \"A132\"   \"f445\"   \"e345\"   \"C{308}\" \"M2244\"  \"Z449\"   \"E18\"\n<\/code><\/pre>\n<p>Si l&rsquo;on veut d\u00e9signer un caract\u00e8re quelconque, alors on peut utiliser la notation <code>.<\/code><\/p>\n<p>Par exemple, si l&rsquo;on souhaite rechercher n&rsquo;importe quel caract\u00e8re (except\u00e9 le retour \u00e0 la ligne) suivi d&rsquo;une lettre minuscule:<\/p>\n<pre><code>str_view_all(c(\"32a\",\"B44\",\"552\",\"98eEf\"),\n             \".[a-z]\")\n\n## [1] \"3{2a}\"     \"B44\"       \"552\"       \"9{8e}{Ef}\"\n<\/code><\/pre>\n<h1>Caract\u00e8res sp\u00e9ciaux<\/h1>\n<p><img decoding=\"async\" src=\"..\/..\/lise.vaudor\/Rfigures\/Expressions_regulieres\/regexp_backslashes.png\" alt=\"\" \/><\/p>\n<p>Si je veux trouver tous les points, points d&rsquo;interrogation ou points d&rsquo;exclamation:<\/p>\n<pre><code>str_view_all(c(\"All\u00f4, John-John?\", \"Ici Joe la frite.\", \"Surprise!\"),\n             \"[\\\\.\\\\?\\\\!]\")\n\n## [1] \"All\u00f4, John-John{?}\"  \"Ici Joe la frite{.}\" \"Surprise{!}\"\n<\/code><\/pre>\n<p>Remarquez qu&rsquo;on ne cherche pas le pattern <code>\"[.?!]\"<\/code>, mais le pattern <code>\"[\\\\.\\\\?\\\\!]\"<\/code>. Voici pourquoi:<\/p>\n<p><code>.<\/code> (comme nous l&rsquo;avons vu pr\u00e9c\u00e9demment), mais aussi <code>?<\/code> et <code>!<\/code> sont des <strong>caract\u00e8res sp\u00e9ciaux<\/strong> dans le cadre des expressions r\u00e9guli\u00e8res. Donc, pour dire qu&rsquo;on parle d&rsquo;un \u00ab\u00a0vrai\u00a0\u00bb point, point d&rsquo;interrogation ou point d&rsquo;exclamation, on utilise l&rsquo;escape character <code>\\<\/code>. L&rsquo;expression r\u00e9guli\u00e8re est donc <code>[\\.\\?\\!]<\/code>&#8230;<\/p>\n<p>Mais on ne s&rsquo;arr\u00eate pas l\u00e0&#8230; En effet, ce n&rsquo;est pas <em>directement<\/em> une expression r\u00e9guli\u00e8re que l&rsquo;on passe \u00e0 la fonction, mais plut\u00f4t une cha\u00eene de caract\u00e8res qui est elle-m\u00eame \u00ab\u00a0transform\u00e9e\u00a0\u00bb en expression r\u00e9guli\u00e8re&#8230; Il faut donc utiliser l&rsquo;escape character <code>\\<\/code> devant les <code>\\<\/code>. Et voil\u00e0 comment on se retrouve \u00e0 passer le pattern <code>\"[\\\\.\\\\?\\\\!]\"<\/code>.<\/p>\n<p>Pour \u00eatre s\u00fbre que vous ayiez bien compris, dans l&rsquo;autre sens, cela donne:<\/p>\n<ul>\n<li>on lui demande un pattern <code>\"\\\\.\"<\/code> <\/li>\n<li>la fonction l&rsquo;interpr\u00e8te comme expression r\u00e9guli\u00e8re <code>\\.<\/code> <\/li>\n<li>on recherche donc un \u00ab\u00a0vrai\u00a0\u00bb <code>.<\/code><\/li>\n<\/ul>\n<p>Mais revenons \u00e0 nos moutons, les classes de caract\u00e8res.<\/p>\n<h1>Caract\u00e8res exclus<\/h1>\n<p>On peut d\u00e9finir une classe de caract\u00e8res en listant les caract\u00e8res qu&rsquo;elle inclut, mais \u00e9galement en listant <strong>l&rsquo;ensemble des caract\u00e8res exclus<\/strong> en utilisant la notation <code>[^...]<\/code>:<\/p>\n<p>Par exemple, pour trouver tous les caract\u00e8res qui ne sont ni une voyelle ni un espace:<\/p>\n<pre><code>str_view_all(\"turlututu chapeau pointu\",\n             \"[^aeiou ]\")\n\n## [1] \"{t}u{r}{l}u{t}u{t}u {c}{h}a{p}eau {p}oi{n}{t}u\"\n<\/code><\/pre>\n<h1>Gammes de caract\u00e8res<\/h1>\n<p>Enfin, on peut d\u00e9finir des classes de caract\u00e8res correspondant \u00e0 des gammes de valeurs en utilisant la notation <code>[...-...]<\/code><\/p>\n<p>Par exemple, pour trouver tous les chiffres entre 1 et 5:<\/p>\n<pre><code>str_view_all(c(\"3 petits cochons\", \"101 dalmations\", \"7 nains\"),\n             \"[1-5]\")\n\n## [1] \"{3} petits cochons\" \"{1}0{1} dalmations\" \"7 nains\"\n<\/code><\/pre>\n<p>Pour trouver toutes les lettres entre A et F:<\/p>\n<pre><code>str_view_all(c(\"A132g\",\"f445E\",\"e345Z\",\"C308d\",\"M2244\",\"Z449\",\"E18M\"),\n             \"[A-F]\")\n\n## [1] \"{A}132g\" \"f445{E}\" \"e345Z\"   \"{C}308d\" \"M2244\"   \"Z449\"    \"{E}18M\"\n<\/code><\/pre>\n<p>Pour trouver toutes les lettres entre A et F et a et e:<\/p>\n<pre><code>str_view_all(c(\"A132\",\"f445\",\"e345\",\"C308\",\"M2244\",\"Z449\",\"E18\"),\n             \"[A-Fa-e]\")\n\n## [1] \"{A}132\" \"f445\"   \"{e}345\" \"{C}308\" \"M2244\"  \"Z449\"   \"{E}18\"\n<\/code><\/pre>\n<h1>Classes pr\u00e9d\u00e9finies<\/h1>\n<p>Notez qu&rsquo;il existe des classes de caract\u00e8res pr\u00e9d\u00e9finies<\/p>\n<p><img decoding=\"async\" src=\"..\/..\/lise.vaudor\/Rfigures\/Expressions_regulieres\/regexp_predifined_classes.png\" alt=\"\" \/><\/p>\n<ul>\n<li><code>\\w<\/code>: un caract\u00e8re alphab\u00e9tique, ou un chiffre, ou un underscore <code>_<\/code><\/li>\n<li><code>[:alnum:]<\/code>: un caract\u00e8re alphanum\u00e9rique (caract\u00e8re alphab\u00e9tique ou chiffre)<\/li>\n<li><code>[:alpha:]<\/code>: une caract\u00e8re alphab\u00e9tique<\/li>\n<li><code>[:lower:]<\/code>: une caract\u00e8re alphab\u00e9tique minuscule<\/li>\n<li><code>[:upper:]<\/code>: une caract\u00e8re alphab\u00e9tique majuscule<\/li>\n<li><code>[:digit:]<\/code> (qu&rsquo;on peut aussi \u00e9crire <code>\\d<\/code>): un chiffre<\/li>\n<li><code>[:punct:]<\/code>: un caract\u00e8re de ponctuation<\/li>\n<li><code>[:space:]<\/code>: un espace (espace simple, tabulation, tabulation verticale, nouvelle ligne, etc.)<\/li>\n<li><code>[:blank:]<\/code>: un \u00ab\u00a0blanc\u00a0\u00bb (espace simple ou tabulation)<\/li>\n<\/ul>\n<h1>Quelques exemples pour bien comprendre<\/h1>\n<p>Une lettre entre A and E, puis un chiffre entre 1 et 6, puis un point, puis \u00ab\u00a0txt\u00a0\u00bb:<\/p>\n<pre><code>str_view_all(c(\"A2.txt\",\"B5.png\",\"C3.txt\",\"E6.txt\",\"E9.txt\",\"F4.txt\"), \n             \"[A-E][1-6]\\\\.txt\")\n\n## [1] \"{A2.txt}\" \"B5.png\"   \"{C3.txt}\" \"{E6.txt}\" \"E9.txt\"   \"F4.txt\"\n<\/code><\/pre>\n<p>Un chiffre suivi d&rsquo;un espace:<\/p>\n<pre><code>str_view_all(c(\"7 nains\",\"3 petits cochons\",\"101 dalmatiens\"), \n             \"[0-9] \")\n\n## [1] \"{7 }nains\"          \"{3 }petits cochons\" \"10{1 }dalmatiens\"\n<\/code><\/pre>\n<p>Un caract\u00e8re suivi d&rsquo;un chiffre suivi d&rsquo;un point:<\/p>\n<pre><code>str_view_all(c(\"\/pouet3.kebop4.kekepwek.kwak\"),\n             \".[0-9]\\\\.\")\n\n## [1] \"\/poue{t3.}kebo{p4.}kekepwek.kwak\"\n<\/code><\/pre>\n<p>Un caract\u00e8re de ponctuation suivi d&rsquo;un espace simple et d&rsquo;une lettre en majuscule:<\/p>\n<pre><code>str_view_all(c(\"All\u00f4? Ici John John.\", \"All\u00f4? ici John-John\"),\n             \"[:punct:] [:upper:]\")\n\n## [1] \"All\u00f4{? I}ci John John.\" \"All\u00f4? ici John-John\"\n<\/code><\/pre>\n<h1>Groupes et r\u00e9f\u00e9rences arri\u00e8res<\/h1>\n<p>Il est possible de cr\u00e9er des groupes au sein des expressions r\u00e9guli\u00e8res, \u00e0 l&rsquo;aide de la notation <code>(...)<\/code><\/p>\n<p>Par exemple, je peux cr\u00e9er un premier groupe d\u00e9fini par une consonne suivie d&rsquo;une voyelle \u00e0 travers l&rsquo;expression r\u00e9guli\u00e8re <code>([^aeiou ][aeiou])<\/code>, et un deuxi\u00e8me groupe d\u00e9fini de la m\u00eame mani\u00e8re.<\/p>\n<p>En l&rsquo;\u00e9tat, utilis\u00e9es avec la fonction str_view_all, l&rsquo;usage des parenth\u00e8ses dans l&rsquo;expression r\u00e9guli\u00e8re n&rsquo;apporte rien de particulier&#8230;<\/p>\n<pre><code>str_view_all(c(\"tili tili woup lala tutu pop\"),\n             \"([^aeiou ][aeiou])([^aeiou ][aeiou])\")\n\n## [1] \"{tili} {tili} woup {lala} {tutu} pop\"\n<\/code><\/pre>\n<p>En revanche, utilis\u00e9es avec la fonction str_match_all, l&rsquo;usage des parenth\u00e8ses permet d&rsquo;isoler diff\u00e9rentes parties du pattern:<\/p>\n<pre><code>str_match_all(c(\"tili tili woup lala tutu pop\"),\n              \"([^aeiou ][aeiou])([^aeiou ][aeiou])\")\n\n## [[1]]\n##      [,1]   [,2] [,3]\n## [1,] \"tili\" \"ti\" \"li\"\n## [2,] \"tili\" \"ti\" \"li\"\n## [3,] \"lala\" \"la\" \"la\"\n## [4,] \"tutu\" \"tu\" \"tu\"\n<\/code><\/pre>\n<p>L&rsquo;usage conjoint des <strong>groupes<\/strong> et des <strong>r\u00e9f\u00e9rences arri\u00e8res<\/strong> permet par ailleurs de rechercher des <strong>r\u00e9p\u00e9titions de motifs<\/strong> dans les patterns.<\/p>\n<p>Ainsi, pour chercher un pattern compos\u00e9 d&rsquo;une consonne suivi d&rsquo;une voyelle, r\u00e9p\u00e9t\u00e9 deux fois, on peut utiliser une r\u00e9f\u00e9rence arri\u00e8re <code>\\1<\/code>, <code>\\2<\/code>, etc. (Comme d&rsquo;habitude, pour passer l&rsquo;expression r\u00e9guli\u00e8re \u00e0 la fonction on utilise un string, donc on double le <code>\\<\/code>):<\/p>\n<pre><code>str_view_all(c(\"turlututu tralala\"),\n             \"([^aeiou ][aeiou])\\\\1\")\n\n## [1] \"turlu{tutu} tra{lala}\"\n<\/code><\/pre>\n<p>Ici on recherche un motif (il n&rsquo;y en a qu&rsquo;un, donc il est num\u00e9rot\u00e9 \u00ab\u00a01\u00a0\u00bb), r\u00e9p\u00e9t\u00e9 imm\u00e9diatement apr\u00e8s sa premi\u00e8re occurrence.<\/p>\n<p>Imaginons qu&rsquo;on ait plusieurs motifs. La <strong>num\u00e9rotation des motifs se fait selon l&rsquo;ordre dans lequel ils apparaissent dans l&rsquo;expression r\u00e9guli\u00e8re<\/strong>, et on peut ensuite placer la r\u00e9f\u00e9rence arri\u00e8re \u00e0 l&#8217;emplacement de notre choix:<\/p>\n<p>Motif 1 puis motif 2 puis motif 1 puis motif 2:<\/p>\n<pre><code>str_view_all(c(\"tututuyutu, tututuyutu, tutuyutuyutuyutuyutututuyutu\"),\n             \"([^aeiou ][aeiou])([^aeiou ][aeiou])\\\\1\\\\2\")\n\n## [1] \"tututuyutu, tututuyutu, tu{tuyutuyu}{tuyutuyu}tututuyutu\"\n<\/code><\/pre>\n<p>Motif 1 puis motif 1 puis motif 1 puis motif 2 puis motif 1:<\/p>\n<pre><code>str_view_all(c(\"tututuyutu, tututuyutu, tutuyutuyutuyutuyutututuyutu\"),\n             \"([^aeiou ][aeiou])\\\\1\\\\1([^aeiou ][aeiou])\\\\1\")\n\n## [1] \"{tututuyutu}, {tututuyutu}, tutuyutuyutuyutuyu{tututuyutu}\"\n<\/code><\/pre>\n<p>Motif 1 puis motif 2 puis motif 2 puis motif 1:<\/p>\n<pre><code>str_view_all(c(\"tutuyututuyutu\"),\n             \"([^aeiou ][aeiou])([^aeiou ][aeiou])\\\\2\\\\1\")\n\n## [1] \"tutu{yututuyu}tu\"\n<\/code><\/pre>\n<h2>Quantificateurs<\/h2>\n<p>Les quantificateurs permettent de pr\u00e9ciser le <strong>nombre d&rsquo;occurrences cons\u00e9cutives<\/strong> d&rsquo;une classe de caract\u00e8res ou d&rsquo;un groupe.<\/p>\n<p><img decoding=\"async\" src=\"..\/..\/lise.vaudor\/Rfigures\/Expressions_regulieres\/regexp_quantifiers.png\" alt=\"\" \/><\/p>\n<h1>z\u00e9ro ou un<\/h1>\n<p>On utilise la notation <code>?<\/code> \u00e0 la suite du caract\u00e8re ou motif recherch\u00e9.<\/p>\n<pre><code>str_view_all(c(\"file1990\",\"fileB1990\",\"file2005\",\"fileAbis2005\",\"fileA2005\"),\n             \"file[:alpha:]?\\\\d\\\\d\\\\d\\\\d\")\n\n## [1] \"{file1990}\"   \"{fileB1990}\"  \"{file2005}\"   \"fileAbis2005\" \"{fileA2005}\"\n<\/code><\/pre>\n<h1>z\u00e9ro ou plus<\/h1>\n<p>On utilise la notation <code>*<\/code> \u00e0 la suite du caract\u00e8re ou motif recherch\u00e9.<\/p>\n<pre><code>str_view_all(c(\"fileA0885\",\"fileA\",\"fileB\",\"fileA862\"),\n             \"fileA\\\\d*\")\n\n## [1] \"{fileA0885}\" \"{fileA}\"     \"fileB\"       \"{fileA862}\"\n<\/code><\/pre>\n<h1>un ou plus<\/h1>\n<p>On utilise la notation <code>+<\/code> \u00e0 la suite du caract\u00e8re ou motif recherch\u00e9.<\/p>\n<pre><code>str_view_all(c(\"fileA0885\",\"fileA\",\"fileB\",\"fileA862\"),\n             \"fileA\\\\d+\")\n\n## [1] \"{fileA0885}\" \"fileA\"       \"fileB\"       \"{fileA862}\"\n<\/code><\/pre>\n<h1>exactement n fois<\/h1>\n<p>On utilise la notation <code>{n}<\/code> \u00e0 la suite du caract\u00e8re ou motif recherch\u00e9.<\/p>\n<pre><code>str_view_all(c(\"fileA0885.txt\",\"fileA15.txt\",\"fileA1.txt\",\"fileA862.txt\",\"fileA56998.txt\"),\n             \"fileA\\\\d{4}\\\\.txt\")\n\n## [1] \"{fileA0885.txt}\" \"fileA15.txt\"     \"fileA1.txt\"      \"fileA862.txt\"    \"fileA56998.txt\"\n<\/code><\/pre>\n<h1>de n \u00e0 m fois<\/h1>\n<p>On utilise la notation <code>{n,m}<\/code> \u00e0 la suite du caract\u00e8re ou motif recherch\u00e9.<\/p>\n<pre><code>str_view_all(c(\"fileA0885.txt\",\"fileA15.txt\",\"fileA1.txt\",\"fileA862.txt\",\"fileA56998.txt\"),\n             \"fileA\\\\d{2,4}\\\\.txt\")\n\n## [1] \"{fileA0885.txt}\" \"{fileA15.txt}\"   \"fileA1.txt\"      \"{fileA862.txt}\"  \"fileA56998.txt\"\n<\/code><\/pre>\n<h1>Quelques exemples pour bien comprendre<\/h1>\n<pre><code>str_view_all(c(\"radio gaga gaga\", \"radio gougou\"),\n                \"radio\\\\s(\\\\w{2,3})\\\\1\")\n\n## [1] \"{radio gaga} gaga\" \"{radio gougou}\"\n\nstr_view_all(c(\"Mon adresse c'est joe.lafrite@patates.com\",\n               \"Ecris-moi \u00e0 petit.bertrand69@croquettes.com\"),\n                \"\\\\w+\\\\.[:alpha:]+\\\\d*@\\\\w+\\\\.\\\\w+\")\n\n## [1] \"Mon adresse c'est {joe.lafrite@patates.com}\"   \"Ecris-moi \u00e0 {petit.bertrand69@croquettes.com}\"\n<\/code><\/pre>\n<h2>Ancres et assertions avant-arri\u00e8re<\/h2>\n<p>Les ancres permettent de <strong>sp\u00e9cifier l&#8217;emplacement du motif<\/strong> par rapport \u00e0 un mot ou \u00e0 un string.<\/p>\n<p><img decoding=\"async\" src=\"..\/..\/lise.vaudor\/Rfigures\/Expressions_regulieres\/regexp_anchors.png\" alt=\"\" \/><\/p>\n<h1>D\u00e9but d&rsquo;un string<\/h1>\n<p>L&rsquo;ancre <code>^<\/code> fait r\u00e9f\u00e9rence au d\u00e9but d&rsquo;un string.<\/p>\n<pre><code># une majuscule en d\u00e9but de string:\nstr_view_all(c(\"Ah! C'est toi John-John?\",\"Ben \u00e7a alors, Joe la Frite!\"),\n             \"^[:upper:]\")\n\n## [1] \"{A}h! C'est toi John-John?\"    \"{B}en \u00e7a alors, Joe la Frite!\"\n<\/code><\/pre>\n<h1>Fin d&rsquo;un string<\/h1>\n<p>L&rsquo;ancre <code>$<\/code> fait r\u00e9f\u00e9rence \u00e0 la fin d&rsquo;un string.<\/p>\n<pre><code>str_view_all(c(\"All\u00f4? John-John?\"),\n             \"\\\\?$\")\n\n## [1] \"All\u00f4? John-John{?}\"\n<\/code><\/pre>\n<h1>Limites d&rsquo;un mot<\/h1>\n<p>L&rsquo;ancre <code>\\\\b<\/code> fait r\u00e9f\u00e9rence au d\u00e9but ou \u00e0 la fin d&rsquo;un mot.<\/p>\n<pre><code># tous les mots se terminant par \"a\":\nstr_view_all(c(\"Carla\",\"Lea\",\"Armelle\",\"Marie\",\"Lisa\",\"Alexia\",\"Nina\"),\n             \"a\\\\b\")\n\n## [1] \"Carl{a}\"  \"Le{a}\"    \"Armelle\"  \"Marie\"    \"Lis{a}\"   \"Alexi{a}\" \"Nin{a}\"\n\n# tous les mots commen\u00e7ant par une majuscule:\nstr_view_all(c(\"hey Bertrand, aLLeZ vIeNs, il y aura Magda et John-John!\"),\n             \"\\\\b[:upper:]\")\n\n## [1] \"hey {B}ertrand, aLLeZ vIeNs, il y aura {M}agda et {J}ohn-{J}ohn!\"\n<\/code><\/pre>\n<h1>Assertions avant-arri\u00e8re<\/h1>\n<p>Ces assertions servent \u00e0 <strong>v\u00e9rifier si un motif existe dans un pattern, sans inclure ce motif dans le r\u00e9sultat<\/strong>.<\/p>\n<p><img decoding=\"async\" src=\"..\/..\/lise.vaudor\/Rfigures\/Expressions_regulieres\/regexp_lookarounds.png\" alt=\"\" \/><\/p>\n<ul>\n<li><code>(?=...)<\/code>: Assertion avant<\/li>\n<li><code>(?!...)<\/code>: Assertion avant n\u00e9gative<\/li>\n<li><code>(?&lt;=...)<\/code>: Assertion arri\u00e8re<\/li>\n<li><code>(?&lt;!...)<\/code>: Assertion arri\u00e8re n\u00e9gative<\/li>\n<\/ul>\n<p>Exemple d&rsquo;<strong>assertion avant<\/strong>: on cherche les nombres (<code>\\b\\d+\\b<\/code>) qui sont suivis de \u00a0\u00bb dalmatiens\u00a0\u00bb<\/p>\n<pre><code>str_view_all( c(\"3 dalmatiens\", \"12 labradors\",\"101 dalmatiens\",\"4 loulous\"),\n              \"\\\\b\\\\d+\\\\b(?= dalmatiens)\")\n\n## [1] \"{3} dalmatiens\"   \"12 labradors\"     \"{101} dalmatiens\" \"4 loulous\"\n<\/code><\/pre>\n<p>Exemple d&rsquo;<strong>assertion avant n\u00e9gative<\/strong>: on cherche les nombres (<code>\\b\\d+\\b<\/code>) qui ne sont pas suivi de \u00a0\u00bb dalmatiens\u00a0\u00bb<\/p>\n<pre><code>str_view_all( c(\"3 dalmatiens\", \"12 labradors\",\"101 dalmatiens\",\"4 loulous\"),\n              \"\\\\d+\\\\b(?! dalmatiens)\")\n\n## [1] \"3 dalmatiens\"   \"{12} labradors\" \"101 dalmatiens\" \"{4} loulous\"\n<\/code><\/pre>\n<p>Exemple d&rsquo;<strong>assertion arri\u00e8re<\/strong>: on cherche les mots commen\u00e7ant par une majuscule (<code>[:upper:][:lower:]*<\/code>) pr\u00e9c\u00e9d\u00e9s de \u00ab\u00a0Mr \u00ab\u00a0:<\/p>\n<pre><code>str_view_all( c(\"Mr X\", \"Mr Robot\",\"James Bond\",\"Mr Clean\",\"Jon Snow\"),\n              \"(?&lt;=Mr )[:upper:][:lower:]*\")\n\n## [1] \"Mr {X}\"     \"Mr {Robot}\" \"James Bond\" \"Mr {Clean}\" \"Jon Snow\"\n<\/code><\/pre>\n<p>Exemple d&rsquo;<strong>assertion arri\u00e8re n\u00e9gative<\/strong>: on cherche tous les mots commen\u00e7ant par une majuscule et finissant les strings (<code>[:upper:][:lower:]*$<\/code>) pr\u00e9c\u00e9d\u00e9s par autre chose que \u00ab\u00a0Mr \u00ab\u00a0:<\/p>\n<pre><code>str_view_all( c(\"Mr X\", \"Mr Robot\",\"James Bond\",\"Mr Clean\",\"Jon Snow\"),\n              \"(?&lt;!Mr )[:upper:][:lower:]*$\")\n\n## [1] \"Mr X\"         \"Mr Robot\"     \"James {Bond}\" \"Mr Clean\"     \"Jon {Snow}\"\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Les expressions r\u00e9guli\u00e8res, pour quoi faire? Les expressions r\u00e9guli\u00e8res servent \u00e0 effectuer des recherches de patterns dans les strings en d\u00e9finissant les r\u00e8gles qui r\u00e9gissent ces patterns. Par exemple, si je cherche \u00e0 trouver le mot \u00ab\u00a0turlututu\u00a0\u00bb dans le string \u00ab\u00a0turlututu chapeau pointu\u00a0\u00bb, mon pattern est simplement \u00ab\u00a0turlututu\u00a0\u00bb. Si en revanche, je cherche \u00e0 trouver tous les mots d\u00e9butant par une majuscule qui ne correspondent pas \u00e0 un d\u00e9but de.. <a href=\"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/strings-et-expressions-regulieres\/\">Read More<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-796","post","type-post","status-publish","format-standard","hentry","category-tous-les-posts"],"_links":{"self":[{"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/posts\/796","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/comments?post=796"}],"version-history":[{"count":31,"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/posts\/796\/revisions"}],"predecessor-version":[{"id":1077,"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/posts\/796\/revisions\/1077"}],"wp:attachment":[{"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/media?parent=796"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/categories?post=796"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/tags?post=796"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}