{"id":4811,"date":"2021-10-21T13:39:09","date_gmt":"2021-10-21T12:39:09","guid":{"rendered":"https:\/\/thinkr.fr\/abcdr\/?p=4811"},"modified":"2021-10-21T13:39:16","modified_gmt":"2021-10-21T12:39:16","slug":"comment-extraire-un-motif-dune-chaine-de-caracteres-avec-une-expression-reguliere-ou-regex","status":"publish","type":"post","link":"https:\/\/thinkr.fr\/abcdr\/comment-extraire-un-motif-dune-chaine-de-caracteres-avec-une-expression-reguliere-ou-regex\/","title":{"rendered":"Comment extraire un motif d&rsquo;une cha\u00eene de caract\u00e8res avec une expression r\u00e9guli\u00e8re ou regex"},"content":{"rendered":"\n<p><strong>Analyser des donn\u00e9es demande de savoir manipuler aussi du texte. Ce que nous appelons texte en tant qu\u2019humain est interpr\u00e9t\u00e9 par R comme une <em>cha\u00eene de caract\u00e8res<\/em>.<\/strong><\/p>\n<p>Le type de donn\u00e9e correspondant dans R est appel\u00e9: <code>character<\/code>.<\/p>\n<pre class=\"r\"><code>class(\"abcdR\")<\/code><\/pre>\n<pre><code>## [1] \"character\"<\/code><\/pre>\n<p>Il est parfois n\u00e9cessaire d\u2019extraire des motifs particuliers de cha\u00eenes de caract\u00e8res. Pour ce faire on peut utiliser des <em>expressions r\u00e9guli\u00e8res<\/em> ou <strong>regex<\/strong> en anglais.<\/p>\n<p>Pour cela nous allons utiliser <code>{stringr}<\/code>, un package du <a href=\"https:\/\/www.tidyverse.org\/\" target=\"_blank\" rel=\"noopener\">tidyverse<\/a>.<\/p>\n<pre class=\"r\"><code>library(stringr)<\/code><\/pre>\n<p>Consid\u00e9rons un vecteur de noms de fichiers csv.<\/p>\n<pre class=\"r\"><code>noms_fichiers &lt;- c(\"pop_FRA_2019.csv\", \"pop_ITA_2020.csv\", \"pop_ESP_2019.csv\")<\/code><\/pre>\n<p>Comment extraire le code iso3 (<code>FRA<\/code>, <code>ITA<\/code>\u2026) ?<\/p>\n<pre class=\"r\"><code>str_extract(string = noms_fichiers, pattern = \"[A-Z]{3}\")<\/code><\/pre>\n<pre><code>## [1] \"FRA\" \"ITA\" \"ESP\"<\/code><\/pre>\n<p>Ici le motif (<code>pattern<\/code>) \u00e0 extraire correspond \u00e0 une lettre majuscule <code>[A-Z]<\/code> r\u00e9p\u00e9t\u00e9e exactement <code>{3}<\/code> fois. Facile !<\/p>\n<p>Mais malheureusement la vie n\u2019est jamais aussi simple\u2026<\/p>\n<pre class=\"r\"><code>noms_fichiers &lt;- c(\"pop_fra_2019.csv\", \"pop_ita_2020.csv\", \"pop_esp_2019.csv\")<\/code><\/pre>\n<p>Dans ce cas pr\u00e9cis notre exemple pr\u00e9c\u00e9dent ne fonctionne plus car tout est en minuscule. Nous devrions utiliser la version minuscule du <code>pattern<\/code>: <code>\"[a-z]{3}\"<\/code>, une lettre minuscule <code>[a-z]<\/code> r\u00e9p\u00e9t\u00e9e exactement <code>{3}<\/code> fois. Mais cela ne correspond plus \u00e0 un motif unique.<\/p>\n<pre class=\"r\"><code>str_extract(noms_fichiers, \"[a-z]{3}\")<\/code><\/pre>\n<pre><code>## [1] \"pop\" \"pop\" \"pop\"<\/code><\/pre>\n<p>Il est alors n\u00e9cessaire de sortir l\u2019artillerie lourde\u2026<\/p>\n<pre class=\"r\"><code>str_extract(noms_fichiers, \"(?&lt;=pop_)[a-z]{3}(?=_\\\\d{4})\")<\/code><\/pre>\n<pre><code>## [1] \"fra\" \"ita\" \"esp\"<\/code><\/pre>\n<p>Ce motif, <code>\"(?&lt;=pop_)[a-z]{3}(?=_\\\\d{4})\"<\/code> se lit,<\/p>\n<ul>\n<li><code>(?&lt;=pop_)<\/code>, ce qui est pr\u00e9c\u00e9d\u00e9 <code>(?&lt;=)<\/code> par <code>pop_<\/code>.<\/li>\n<li><code>\"[a-z]{3}\"<\/code>, une lettre minuscule <code>[A-Z]<\/code> r\u00e9p\u00e9t\u00e9e exactement <code>{3}<\/code>.<\/li>\n<li><code>(?=_\\\\d{4})<\/code>, ce qui est suivi <code>(?=)<\/code> par un chiffre <code>\\\\d<\/code> r\u00e9p\u00e9t\u00e9 exactement <code>{4}<\/code> fois.<\/li>\n<\/ul>\n<p>Pour \u00eatre totalement rigoureux, on peut rajouter:<\/p>\n<pre class=\"r\"><code>str_extract(noms_fichiers, \"(?&lt;=^pop_)[a-z]{3}(?=_\\\\d{4}\\\\.csv$)\")<\/code><\/pre>\n<pre><code>## [1] \"fra\" \"ita\" \"esp\"<\/code><\/pre>\n<ul>\n<li><code>^<\/code> commence par <code>pop_<\/code>.<\/li>\n<li><code>\\\\.csv<\/code> se termine <code>$<\/code> par l\u2019extension \u201cpoint\u201d <code>\\\\.<\/code>, <code>csv<\/code>.<\/li>\n<\/ul>\n<p>Il est parfois complexe d\u2019utiliser ce genre de symboles appel\u00e9s <em>lookarounds<\/em>, <code>(?=)<\/code> et <code>(?&lt;=)<\/code>. Une alternative plus simple est de tirer profit de la notion de <em>groupe<\/em>.<\/p>\n<p>En regex on d\u00e9finit un groupe en utilisant des parenth\u00e8ses.<\/p>\n<pre class=\"r\"><code>str_replace(\n  string = noms_fichiers, \n  pattern = \"^pop_([a-z]{3})_\\\\d{4}\\\\.csv$\",\n  replacement = \"\\\\1\"\n)<\/code><\/pre>\n<pre><code>## [1] \"fra\" \"ita\" \"esp\"<\/code><\/pre>\n<p>Ici on d\u00e9finit le motif complet en rajoutant des parenth\u00e8ses autour du motif \u00e0 extraire: <code>([a-z]{3})<\/code>. On demande \u00e0 <code>str_replace()<\/code> de remplacer la cha\u00eene compl\u00e8te par le premier groupe d\u00e9finit (le seul et l\u2019unique) avec <code>\\\\1<\/code>.<\/p>\n<p>Et voil\u00e0, les regex sont une technique difficile \u00e0 appr\u00e9hender pour les d\u00e9butants mais \u00f4 combien utile \u00e0 celles ou ceux qui la ma\u00eetrisent.<\/p>\n<p>Pour en savoir plus:<\/p>\n<ul>\n<li><a href=\"https:\/\/raw.githubusercontent.com\/rstudio\/cheatsheets\/master\/strings.pdf\" target=\"_blank\" rel=\"noopener\">cheatsheet {<code>stringr<\/code>}<\/a><\/li>\n<li>Article <a href=\"https:\/\/thinkr.fr\/r-les-expressions-regulieres\/\">\u00ab\u00a0R et les expressions r\u00e9guli\u00e8res\u00a0\u00bb<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Analyser des donn\u00e9es demande de savoir manipuler aussi du texte. Ce que nous appelons texte en tant qu\u2019humain est interpr\u00e9t\u00e9 par R comme une cha\u00eene de caract\u00e8res. Le type de donn\u00e9e correspondant dans R est appel\u00e9: character. class(\u00ab\u00a0abcdR\u00a0\u00bb) ## [1] \u00ab\u00a0character\u00a0\u00bb Il est parfois n\u00e9cessaire d\u2019extraire des motifs particuliers de cha\u00eenes de caract\u00e8res. Pour ce faire on peut utiliser des expressions r\u00e9guli\u00e8res ou regex en anglais. Pour cela nous allons utiliser {stringr}, un package du tidyverse. library(stringr) Consid\u00e9rons un vecteur de noms de fichiers csv. noms_fichiers &lt;- c(\u00ab\u00a0pop_FRA_2019.csv\u00a0\u00bb, \u00ab\u00a0pop_ITA_2020.csv\u00a0\u00bb, \u00ab\u00a0pop_ESP_2019.csv\u00a0\u00bb) Comment extraire le code iso3 (FRA, ITA\u2026) ? str_extract(string = noms_fichiers, pattern = \u00ab\u00a0[A-Z]{3}\u00a0\u00bb) ##<a class=\"more-link\" href=\"https:\/\/thinkr.fr\/abcdr\/comment-extraire-un-motif-dune-chaine-de-caracteres-avec-une-expression-reguliere-ou-regex\/\">Read More &rarr;<\/a><\/p>\n","protected":false},"author":16,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","rop_custom_images_group":[],"rop_custom_messages_group":[],"rop_publish_now":"initial","rop_publish_now_accounts":{"twitter_399453572_399453572":""},"rop_publish_now_history":[],"rop_publish_now_status":"pending","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[4,41,22],"tags":[43,42],"class_list":{"0":"entry","1":"post","2":"publish","3":"author-antoine","4":"post-4811","6":"format-standard","7":"category-base-indispensable","8":"category-chaines-de-caracteres","9":"category-tidyverse","10":"post_tag-regex","11":"post_tag-stringr"},"acf":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p9O7Sx-1fB","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/thinkr.fr\/abcdr\/wp-json\/wp\/v2\/posts\/4811","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thinkr.fr\/abcdr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thinkr.fr\/abcdr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thinkr.fr\/abcdr\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/thinkr.fr\/abcdr\/wp-json\/wp\/v2\/comments?post=4811"}],"version-history":[{"count":1,"href":"https:\/\/thinkr.fr\/abcdr\/wp-json\/wp\/v2\/posts\/4811\/revisions"}],"predecessor-version":[{"id":4813,"href":"https:\/\/thinkr.fr\/abcdr\/wp-json\/wp\/v2\/posts\/4811\/revisions\/4813"}],"wp:attachment":[{"href":"https:\/\/thinkr.fr\/abcdr\/wp-json\/wp\/v2\/media?parent=4811"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thinkr.fr\/abcdr\/wp-json\/wp\/v2\/categories?post=4811"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thinkr.fr\/abcdr\/wp-json\/wp\/v2\/tags?post=4811"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}