tag:linuxfr.org,2005:/tags/regex/public
LinuxFr.org : les contenus étiquetés avec « regex »
2023-07-16T20:57:06+02:00
/favicon.png
tag:linuxfr.org,2005:Post/43729
2023-07-10T20:01:26+02:00
2023-07-10T20:02:58+02:00
Renommage de fichier - regex
<p>Bonjour, </p>
<p>J'aurais besoin de renommer en masse des fichiers.<br>
le nom de fichier est de la forme<br>
text1.00B00.text2.ext</p>
<p>text1 est une chaine de caractère de longueur variable<br>
. un point<br>
00 un chiffre sur 1 ou 2 digit<br>
B la lettre B fixe<br>
00 un chiffre sur 1 ou 2 digit<br>
. un point<br>
text2 est une autre chaine de caractère de longueur variable<br>
.ext l'extension du fichier </p>
<p>le besoin est de remplacer les 2 zones de chiffres par le meme chiffre mais sur 2 digit, exemple:<br>
abcd.1B21.efg.hi.txt <br>
par <br>
abcd.01B21.efg.hi.txt </p>
<p>Pour tester, j'utilise <a href="https://www.toutjavascript.com/service/regexp.php">Regex en ligne </a></p>
<p>J'ai un début de regle pour attraper les chiffres mais je suis loin du compte<br>
regle <br>
<sup>.([0-9]{2})B([0-9]{2}).(.*)$</sup></p>
<p>cible <br>
<sup>.\$1\x`{mathjax}</sup> 2.`</p>
<p>Merci pour votre aide</p>
<p>PS: ce n'est pas la copie à rendre pour demain ( j'ai passé l'age ;-) ) , je n'y connais rien au regexp, j'ai juste besoin d'un coup de main.</p>
<div><a href="https://linuxfr.org/forums/programmationautre/posts/renommage-de-fichier-regex.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/132674/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/forums/programmationautre/posts/renommage-de-fichier-regex#comments">ouvrir dans le navigateur</a>
</p>
dr191
https://linuxfr.org/nodes/132674/comments.atom
tag:linuxfr.org,2005:Post/43724
2023-07-06T19:24:27+02:00
2023-07-06T19:24:27+02:00
Problème sed
<p>Bonjour,<br>
Je souhaite modifier le fichier ci-dessous et ajouter dans la ligne condition avant le /1 /6 et /4 le trigramme TST afin d'avoir un résultat de cette manière tout en gardant le contenu du fichier :</p>
<p>VariableXXXXTST/1</p>
<p>Auriez-vous une idée svp ?</p>
<p>Test.txt =</p>
<p>Extrait 1<br>
Definiton : insert-ligne<br>
Condition = machine/dev<br>
Descritption : définition ligne</p>
<p>Extrait 2 : <br>
Definiton 2 : insert-<br>
Condition = machine-dev. OODEF VariableXXXX/1<br>
Descritption : définition ligne</p>
<p>Extrait 3 : <br>
Definiton 1 : insert-ligne<br>
Condition = machine/dev. Traitementligne/6<br>
Descritption : définition traitement</p>
<p>Extrait 4 :<br>
Definiton 1 : isuppression <br>
Condition = machine.ksh VariableX25XXX/4<br>
Descritption : définition ligne</p>
<div><a href="https://linuxfr.org/forums/programmation-shell/posts/probleme-sed.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/132635/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/forums/programmation-shell/posts/probleme-sed#comments">ouvrir dans le navigateur</a>
</p>
babi307
https://linuxfr.org/nodes/132635/comments.atom
tag:linuxfr.org,2005:Diary/40012
2021-11-29T19:57:11+01:00
2021-11-29T19:57:11+01:00
La commande ack, one step beyond grep !
Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr
<p>L'URL du site de la commande ack annonce la couleur<sup id="fnref1"><a href="#fn1">1</a></sup> : <a href="https://beyondgrep.com/">https://beyondgrep.com/</a>. J'ai l'habitude d’agripper les motifs avec grep, mais je m'essaie depuis quelques temps à les acquérir avec ack <sup id="fnref2"><a href="#fn2">2</a></sup>. Le deuxième et dernier journal sur cette commande datant d'avril 2013 (voir le tag <a href="//linuxfr.org/tags/ack/public">ack</a>), il est temps de faire une piqûre de rappel aux citoyens du libre.</p>
<h2 id="toc-version-3">Version 3</h2>
<p>En 2019, ack est passée en version 3. La version actuelle est la 3.5.0 (mars 2021), et la version disponible dans Ubuntu 21.10 est la 3.4.0. Les nouveautés sont résumées sur la page principale du site.</p>
<p>La commande est écrite en Perl 5 et les dépendances sont minimales : </p>
<pre><code class="bash">$ apt show ack
<span class="o">[</span>...<span class="o">]</span>
Depends: libfile-next-perl <span class="o">(</span>><span class="o">=</span> <span class="m">1</span>.18<span class="o">)</span>, perl:any
Breaks: ack-grep <span class="o">(</span><<span class="o">=</span> <span class="m">2</span>.14-5~<span class="o">)</span>
Replaces: ack-grep <span class="o">(</span><<span class="o">=</span> <span class="m">2</span>.14-5~<span class="o">)</span>
<span class="o">[</span>...<span class="o">]</span></code></pre>
<p>Cela permet de la proposer facilement pour la plupart des systèmes d'exploitation : Linux, macOS, *BSD et Windows.</p>
<p>On voit également que dans Ubuntu la commande s'appelait auparavant <code>ack-grep</code>, soit 100 % plus long que <code>grep</code>. Devenue <code>ack</code>, elle prend l'avantage en étant 25 % plus courte ;-)</p>
<h2 id="toc-usages">Usages</h2>
<h3 id="toc-chercher-dans-les-contenus-des-fichiers">Chercher dans les contenus des fichiers</h3>
<p>Étant écrite en Perl, ack utilise bien sûr les expressions régulières Perl <sup id="fnref3"><a href="#fn3">3</a></sup> de façon native. L'usage en est très simple :</p>
<p><code>ack [options] PATTERN [FILE...]</code></p>
<p>Un des avantages de ack sur grep est qu'elle utilise par défaut un certain nombre d'options utiles : récursion des répertoires, affichage des numéros de lignes, coloration syntaxique et surbrillance du motif recherché (sauf redirection)… De plus, elle ignore par défaut de nombreux fichiers (images, archives, sauvegardes, PDF…) et répertoires (<code>.git</code>, <code>__pycache__</code>, <code>CMakeFiles</code>…), ce qui participe à sa rapidité. La commande <code>ack --dump</code> vous en donnera la liste avec une syntaxe limpide.</p>
<p>Les principales fonctionnalités de ack et d'autres alternatives à grep sont résumées dans ce <a href="https://beyondgrep.com/feature-comparison/">tableau</a>. Voici une courte sélection personnelle parmi les nombreuses options disponibles :</p>
<pre><code>-l, --files-with-matches Print filenames with at least one match
-i, --ignore-case Ignore case distinctions in PATTERN
-w, --word-regexp Force PATTERN to match only whole words
-m, --max-count=NUM Stop searching in each file after NUM matches
-C [NUM], --context[=NUM] Print NUM lines (default 2) of output context.
-t X, --type=X Include only X files, where X is a filetype,
e.g. python, html, markdown, etc
-s Suppress error messages about nonexistent or unreadable files.
</code></pre>
<p>Notez que l'option <code>-t</code> peut être utilisée encore plus simplement, par exemple :</p>
<pre><code class="bash">$ ack LinuxFr --markdown</code></pre>
<p>L'option peut facilement être inversée pour au contraire éviter certains fichiers : <code>--nomarkdown</code>. <br>
Pour déterminer le type d'un fichier, la commande se base non seulement sur les extensions des noms de fichiers mais aussi sur les <em>shebang.</em> Les types disponibles peuvent être obtenus avec à nouveau la commande <code>ack --dump</code>.</p>
<h3 id="toc-chercher-dans-les-noms-ou-les-types-de-fichiers">Chercher dans les noms ou les types de fichiers</h3>
<p>Avec l'option <code>-g</code>, on peut chercher le motif dans les noms des fichiers plutôt que dans leur contenu. Par exemple, cherchons des fichiers de configuration cachés :</p>
<pre><code class="bash">$ ack -g ^<span class="o">[</span>.<span class="o">]</span>.*rc$</code></pre>
<p>Avec l'option <code>-f</code> on pourra par exemple afficher simplement la liste des fichiers d'un type donné présents dans une arborescence :</p>
<pre><code class="bash">$ ack -f --shell</code></pre>
<h2 id="toc-personnalisation">Personnalisation</h2>
<p>Pour personnaliser le comportement de la commande, on peut créer un fichier de configuration contenant toutes les options et paramètres définis par défaut :</p>
<pre><code class="bash">$ ack --create-ackrc > ~/.ackrc</code></pre>
<p>Exemple concret, j'aime bien utiliser des terminaux avec caractères noirs sur fond jaune clair mais par défaut ack affiche les numéros de ligne en jaune. J'ai donc simplement ajouté dans mon <code>.ackrc</code> la ligne suivante :</p>
<pre><code>--color-lineno=Red
</code></pre>
<h2 id="toc-conclusion">Conclusion</h2>
<p>ack est le genre de commande que l'on risque d'adopter rapidement après essai : simple, rapide, efficace, agréable à utiliser, comportement facilement personnalisable… Il est même possible de l'appeler depuis <a href="https://beyondgrep.com/more-tools/">certains outils</a> tels que vim ou emacs.</p>
<p>Mais il est vrai que grep bénéficie de la prime au premier entrant. Pour un script à distribuer, grep a l'avantage d'être installée sur tous les systèmes libres, même si ses variantes peuvent éventuellement introduire quelques problèmes de compatibilité.</p>
<p>En tout cas, pour votre usage quotidien vous risquez vraiment d'être séduit(e)s par ack.</p>
<h2 id="toc-acknowledgements"><em>Acknowledgements</em></h2>
<p><code>ack</code> est essentiellement l'oeuvre d'<a href="https://blog.petdance.com/">Andy Lester</a>, alias petdance sur <a href="https://github.com/beyondgrep/ack3">GitHub</a>. Elle est sous licence <em>Artistic License 2.0</em>.</p>
<h2 id="toc-références">Références</h2>
<div class="footnotes">
<hr>
<ol>
<li id="fn1">
<p>Prince Buster, <a href="https://www.youtube.com/watch?v=3dnhpK_TnQM">One Step Beyond</a>, 1964. <a href="#fnref1">↩</a></p>
</li>
<li id="fn2">
<p>Auverlot Olivier, "Ack, le super grep", <em>Linux Pratique,</em> HS n°52, octobre 2021, <a href="https://connect.ed-diamond.com/linux-pratique/lphs-052/ack-le-super-grep">https://connect.ed-diamond.com/linux-pratique/lphs-052/ack-le-super-grep</a> <a href="#fnref2">↩</a></p>
</li>
<li id="fn3">
<p>Bernard Desgraupes, <em>Introduction aux expressions régulières,</em> Paris : Vuibert, 2e édition, 2008, ISBN 978-2-7117-4867-9. <a href="#fnref3">↩</a></p>
</li>
</ol>
</div>
<div><a href="https://linuxfr.org/users/vmagnin/journaux/la-commande-ack-one-step-beyond-grep.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/126103/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/vmagnin/journaux/la-commande-ack-one-step-beyond-grep#comments">ouvrir dans le navigateur</a>
</p>
vmagnin
https://linuxfr.org/nodes/126103/comments.atom
tag:linuxfr.org,2005:Bookmark/1874
2020-08-11T19:22:32+02:00
2020-08-11T19:22:32+02:00
les regex expliquées
<a href="https://www.monkeyuser.com/2020/regex-explained/">https://www.monkeyuser.com/2020/regex-explained/</a> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/121286/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/jseb/liens/les-regex-expliquees#comments">ouvrir dans le navigateur</a>
</p>
jseb
https://linuxfr.org/nodes/121286/comments.atom
tag:linuxfr.org,2005:Diary/39186
2020-06-05T12:44:40+02:00
2020-06-05T12:44:40+02:00
SpiderMonkey et V8 travaillent ensemble
Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr
<p>Là, si tu connais ces deux noms, tu te dis que c'est pas possible en fait. Ils doivent bien se connaître, mais <strong>travailler ensemble</strong> ?</p>
<p>Pour ceux qui découvrent : SpiderMonkey est le moteur JavaScript de Firefox, fait par Mozilla, et V8 celui de Chromium/Chrome, maintenu par Google.</p>
<p>Et il se trouve que oui, il y a des domaines où ils y trouvent un intérêt, <strong>les expressions rationnelles</strong> : <a href="https://hacks.mozilla.org/2020/06/a-new-regexp-engine-in-spidermonkey/">https://hacks.mozilla.org/2020/06/a-new-regexp-engine-in-spidermonkey/</a></p>
<p>Visiblement, Mozilla a longtemps utilisé une version patchée du moteur d'expressions rationnelles de V8 (Irregexp), qui est intriqué à ce dernier. Et puis avec les modifications du standard, ça passait plus.</p>
<p>Alors hop, ils se sont remonté les manches, et ont fait une couche d'abstraction. Et ce travail intéresse les développeurs de V8, qui aimeraient bien découpler cette partie du reste. Donc ces derniers ont conseillé les développeurs de SpiderMonkey. En retour, ces derniers contribuent à Irregexp dans le dépôt principal, et corrige des bugs. C'est la fête.</p>
<p>Ce qui veut dire que les expressions rationnelles se comportent de manière identique partout. Enfin, espérons-le…</p>
<div><a href="https://linuxfr.org/users/glandos/journaux/spidermonkey-et-v8-travaillent-ensemble.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/120684/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/glandos/journaux/spidermonkey-et-v8-travaillent-ensemble#comments">ouvrir dans le navigateur</a>
</p>
Glandos
https://linuxfr.org/nodes/120684/comments.atom
tag:linuxfr.org,2005:Bookmark/1145
2020-02-04T22:16:59+01:00
2020-02-04T22:16:59+01:00
Parce que les regex, ça va bien cinq minutes
<a href="https://ihateregex.io/?q=date">https://ihateregex.io/?q=date</a> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/119342/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/davidmarec/liens/parce-que-les-regex-ca-va-bien-cinq-minutes#comments">ouvrir dans le navigateur</a>
</p>
David Marec
https://linuxfr.org/nodes/119342/comments.atom
tag:linuxfr.org,2005:Post/40723
2019-12-13T15:52:34+01:00
2019-12-20T15:16:38+01:00
[Bash] Limiter taille substring
<p>Hello tout le monde.</p>
<p>Dans un exemple type de strings comme suit :</p>
<pre><code>[fuse.ssh] /media/myMountPath 411GB / 921GB (42%)
[glusterfs] /media/superStorage 0.5TB / 1.1TB (50%)
[ext42] /hello/world 25KB / 42KB (57%)
</code></pre>
<p>J'essaye, en bash, de limiter la taille des substrings afin de les empêcher de sortir de leur container.<br>
Donc question :<br>
Comment faire pour limiter la taille des sous chaines [formatage] et /point/de/montage sans toucher au reste.</p>
<div><a href="https://linuxfr.org/forums/programmation-shell/posts/bash-limiter-taille-substring.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/118903/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/forums/programmation-shell/posts/bash-limiter-taille-substring#comments">ouvrir dans le navigateur</a>
</p>
voxdemonix
https://linuxfr.org/nodes/118903/comments.atom
tag:linuxfr.org,2005:Post/40084
2019-04-27T00:15:05+02:00
2019-05-01T16:30:20+02:00
Extraire des données avec la commande grep
<p>Bonjour…</p>
<p>je veux extraire des informations sur le site : aquafortain.site <code>https://www.programmefoot.com/widget</code> (programe foot) on utilisant la commande grep et sed je suis arrivé<br>
à ce résultat</p>
<pre><code class="txt"> <span class="err">Aujourd'hui</span> <span class="err">-</span> <span class="err">vendredi</span> <span class="err">26</span> <span class="err">avril</span>
<span class="err">20:00</span> <span class="err">Nancy</span> <span class="err">AC</span> <span class="err">Ajaccio</span>
<span class="err">20:00</span> <span class="err">Valenciennes</span> <span class="err">Niort</span>
<span class="err">20:00</span> <span class="err">Orléans</span> <span class="err">Troyes</span>
<span class="err">20:00</span> <span class="err">Grenoble</span> <span class="err">Foot</span> <span class="err">38</span> <span class="err">Béziers</span>
<span class="err">20:00</span> <span class="err">Clermont</span> <span class="err">Paris</span> <span class="err">FC</span>
<span class="err">20:00</span> <span class="err">Gazélec</span> <span class="err">Ajaccio</span> <span class="err">Sochaux</span>
<span class="err">20:00</span> <span class="err">Châteauroux</span> <span class="err">Le</span> <span class="err">Havre</span>
<span class="err">20:00</span> <span class="err">Red</span> <span class="err">Star</span> <span class="err">Metz</span>
<span class="err">20:30</span> <span class="err">Augsbourg</span> <span class="err">Bayer</span> <span class="err">Leverkusen</span>
<span class="err">20:45</span> <span class="err">Bordeaux</span> <span class="err">Olympique</span> <span class="err">Lyonnais</span>
<span class="err">21:00</span> <span class="err">Liverpool</span> <span class="err">Huddersfield</span> <span class="err">Town</span>
<span class="err">21:30</span> <span class="err">Rio</span> <span class="err">Ave</span> <span class="err">FC</span> <span class="err">Porto</span>
<span class="err">13:00</span> <span class="err">Athletic</span> <span class="err">Bilbao</span> <span class="err">Deportivo</span> <span class="err">Alavés</span>
<span class="err">13:30</span> <span class="err">Tottenham</span> <span class="err">Hotspur</span> <span class="err">West</span> <span class="err">Ham</span> <span class="err">United</span>
<span class="err">15:00</span> <span class="err">Bologne</span> <span class="err">Empoli</span>
<span class="err">15:00</span> <span class="err">Brest</span> <span class="err">Lens</span>
<span class="err">.....</span> <span class="err">.....</span> <span class="err">.....</span></code></pre>
<p>le probleme c'est que j'arrive pas a intégrer la date et l'heur<br>
athletic bilbao et Alaves se joue le samedi à 13.00</p>
<p>j'ai utilisé cette commande mais sa ne marche pas..<br>
pour afficher la date a côté de l'heur</p>
<pre><code class="sh">grep -o <span class="s1">'><table><caption>\([^"<]*\)</caption><tbody><tr><td.*\([^"<]*\)</td><td'</span></code></pre>
<p>code source :</p>
<pre><code class="html"> Demain - samedi 27 avril
<span class="p"></</span><span class="nt">caption</span><span class="p">><</span><span class="nt">tbody</span><span class="p">><</span><span class="nt">tr</span><span class="p">><</span><span class="nt">td</span> <span class="na">class</span><span class="o">=</span><span class="s">"competition txtcenter hide-smartphone"</span><span class="p">><</span><span class="nt">img</span> <span class="na">src</span><span class="o">=</span><span class="s">"https://images.programmefoot.com/competition/40x40/7.png"</span> <span class="na">alt</span><span class="o">=</span><span class="s">"Logo La Liga Santander"</span>
<span class="p">/></</span><span class="nt">td</span><span class="p">><</span><span class="nt">td</span> <span class="na">class</span><span class="o">=</span><span class="s">"hour txtcenter"</span><span class="p">></span>13:00<span class="p"></</span><span class="nt">td</span><span class="p">><</span><span class="nt">td</span> <span class="na">class</span><span class="o">=</span><span class="s">"match txtcenter"</span><span class="p">><</span><span class="nt">span</span></code></pre>
<div><a href="https://linuxfr.org/forums/programmation-shell/posts/extraire-des-donnees-avec-la-commande-grep.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/117065/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/forums/programmation-shell/posts/extraire-des-donnees-avec-la-commande-grep#comments">ouvrir dans le navigateur</a>
</p>
mino60
https://linuxfr.org/nodes/117065/comments.atom
tag:linuxfr.org,2005:Post/39974
2019-03-17T13:21:19+01:00
2019-03-17T14:11:01+01:00
petit souci avec la commande grep
<p>bonjour a tous !<br>
étant debutant dans le shell je commence doucement mais la j'ai beau faire des recherche mais je ne trouve pas la solution a mon problème:</p>
<pre><code>grep -in '^[0-9]{1 4}" "[a-z]{1 3}" "(1[6-9]\|2[0-9]\|3[0-3]\|75\|78\|9[1-5])' $1
</code></pre>
<p>je souhaite récupérer les ligne commençant par :<br>
1 a 4 chiffre puis <br>
un espace puis <br>
1 a 3 lettre puis<br>
la sa se complique un peut : (sois un chiffre entre 16 et 33, sois 75 sois 78 sois 91 a 95</p>
<p>et lors de l'execution de cette commande je n'obtient pas le resultat souhaiter si on peut me dire ou est mon erreur je vous en serai reconnaissant merci d'avance !</p>
<div><a href="https://linuxfr.org/forums/programmation-shell/posts/petit-souci-avec-la-commande-grep.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/116701/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/forums/programmation-shell/posts/petit-souci-avec-la-commande-grep#comments">ouvrir dans le navigateur</a>
</p>
tems
https://linuxfr.org/nodes/116701/comments.atom
tag:linuxfr.org,2005:Diary/38142
2018-10-04T12:21:42+02:00
2018-10-04T12:21:42+02:00
Ligne de commande : les 20 mémos d'un « autodidacte »
Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr
<p>Depuis avril 2018 j'ai eu l'occasion de publier sur le Grimoire-Command.es les 20 mémos du précédent secrétaire de <a href="https://gebull.org">Gebull</a> (le LUG de Bressuire).</p>
<p>Les sujets abordés sont variés et représentent quelques décennies de lecture de forum et de tâtonnements, scrupuleusement notés et repris en fiches synthétiques.</p>
<p>Comme le reste du grimoire, ce sont des mémos, des penses-bêtes, pour retrouver rapidement une commande que l'on a déjà utilisée ou aperçue. Comme pour les grimoires de jeux de rôle, il faut donc en « apprendre » le contenu, ou au moins avoir regardé ce qu'on peut y trouver. Après, il y a un classement par tags et un moteur de recherche (ça aide quand même).</p>
<p>La mise en page a été grandement facilitée par l'utilisation d'AsciiDoc (AsciiDoctor) et de Pygment comme détaillé sur la page <a href="https://www.grimoire-command.es/pages/a_propos.html">à propos</a>. J'ai enrichi le contenu de nombreux exemples de sortie console, de 15 ans d'expérience personnelle, des commandes déjà citées dans le grimoire et des retours (parfois nombreux aussi) que j'ai eus via <a href="https://mamot.fr/@Siltaer">Mastodon</a>.</p>
<p>Un mémo d'introduction présente quelques conventions et l'index de ces contenus français (et non en anglais voulu transparent comme le reste du grimoire) un peu hors série du Grimoire-Command.es intermédiaires entre les habituelles commandes courtes et les récits long bilingues plus récents : <a href="https://www.grimoire-command.es/2018/memo_0.html">https://www.grimoire-command.es/2018/memo_0.html</a></p>
<p><a href="https://www.grimoire-command.es/2018/memo_1.html">Memo_1 : parcourir les dossiers et lister les fichiers</a><br>
<a href="https://www.grimoire-command.es/2018/memo_2.html">Memo_2 : gérer les dossiers, bouger les fichiers</a><br>
<a href="https://www.grimoire-command.es/2018/memo_3.html">Memo_3 : gérer les utilisateurs</a><br>
<a href="https://www.grimoire-command.es/2018/memo_4.html">Memo_4 : flux de données</a><br>
<a href="https://www.grimoire-command.es/2018/memo_5.html">Memo_5 : chaînes de caractères et sous-invocation de shells</a><br>
<a href="https://www.grimoire-command.es/2018/memo_6.html">Memo_6 : Chercher du texte, des fichiers…</a><br>
<a href="https://www.grimoire-command.es/2018/memo_7.html">Memo_7 : Expression régulières</a><br>
<a href="https://www.grimoire-command.es/2018/memo_8.html">Memo_8 : Compression / décompression</a><br>
<a href="https://www.grimoire-command.es/2018/memo_9.html">Memo_9 : Récupération sur le web</a><br>
<a href="https://www.grimoire-command.es/2018/memo_10.html">Memo_10 : Explorer le matériel</a><br>
<a href="https://www.grimoire-command.es/2018/memo_11.html">Memo_11 : Liens, date et patches</a><br>
<a href="https://www.grimoire-command.es/2018/memo_12.html">Memo_12 : sed</a><br>
<a href="https://www.grimoire-command.es/2018/memo_13.html">Memo_13 : Systèmes de fichier</a><br>
<a href="https://www.grimoire-command.es/2018/memo_14.html">Memo_14 : Émincer des fichiers texte</a><br>
<a href="https://www.grimoire-command.es/2018/memo_15.html">Memo_15 : Accès avancés aux fichiers</a><br>
<a href="https://www.grimoire-command.es/2018/memo_16.html">Memo_16 : APT, Aptitude, Wajig, Dpkg</a><br>
<a href="https://www.grimoire-command.es/2018/memo_17.html">Memo_17 : Accès internet</a><br>
<a href="https://www.grimoire-command.es/2018/memo_18.html">Memo_18 : Le chargeur d'armorçage GRUB 2</a><br>
<a href="https://www.grimoire-command.es/2018/memo_19.html">Memo_19 : Processus</a><br>
<a href="https://www.grimoire-command.es/2018/memo_20.html">Memo_20 : Noyau - Modules</a></p>
<p>À part <code>sed</code>, que je n'ai jamais utilisé consciemment, c'était un plaisir de réviser tout ça. De mémoire, je recommande particulièrement le <em>Mémo 8</em> sur la compression de fichier (j'ai repris les bases dans une grosse introduction), ainsi que le <em>Mémo 10</em> sur les différents moyen de lister ce que GNU+Linux peut dire du matériel sur lequel il tourne, qui m'a beaucoup appris et dont un bon tiers des 16 commandes présentées a été rajouté au gré des réponses sur Mastodon.</p>
<p>Enfin, je vous invite à jeter un œil au reste du grimoire dont j'ai oublié de fêter le récent <a href="https://www.grimoire-command.es/2018/efi_boot_file_not_found.html">100e contenu</a> ici même :-D (j'en ai encore beaucoup sous le coude…).</p>
<p>PS: Avec le même complice, nous avons traduit une partie de la documentation d'AsciiDoctor (la <em>quick syntax reference</em>) de concert avec l'équipe du projet qui s'est montrée très intéressée par cette première traduction de leur documentation. La <em>pull-request</em> principale a été émise il y a 2 semaines, après 6 mois de travail, <a href="https://github.com/asciidoctor/asciidoctor.org/issues/813">hum, et prendra encore un certain temps à être intégrée…</a>. AsciiDoc est un très bon format de "wiki" (léger, complet, lisible), qui pourrait être proposé pour les contenus de LinuxFr.org… (comme le font Github et Gitlab / Framagit).</p>
<div><a href="https://linuxfr.org/users/siltaar/journaux/ligne-de-commande-les-20-memos-d-un-autodidacte.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/115417/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/siltaar/journaux/ligne-de-commande-les-20-memos-d-un-autodidacte#comments">ouvrir dans le navigateur</a>
</p>
Siltaär
https://linuxfr.org/nodes/115417/comments.atom
tag:linuxfr.org,2005:Post/37432
2016-10-22T18:36:58+02:00
2016-10-22T18:36:58+02:00
Expression régulière
<p>Bonjour, je suis un peu perdu dans les expressions régulières. Je voudrais remplacer tous les « A » par des « a » mais seulement dans le cas où « a » n'est pas suivi ou précédé par un ou plusieurs « a ».<br>
Par exemple, l'expression régulière devrait trouver et remplacer</p>
<p>« abord » par « Abord » mais ne devrait pas toucher à</p>
<p>« baabor », « taaabour », mais devrait remplacer</p>
<p>« bbaatar » par « bbaatAr »</p>
<p>J'espère que c'est clair. Merci d'avance pour votre aide.</p><div><a href="https://linuxfr.org/forums/programmationautre/posts/expression-reguliere-104b97a8-b05b-41f6-a397-7443037be620.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/110351/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/forums/programmationautre/posts/expression-reguliere-104b97a8-b05b-41f6-a397-7443037be620#comments">ouvrir dans le navigateur</a>
</p>
pamputt
https://linuxfr.org/nodes/110351/comments.atom
tag:linuxfr.org,2005:News/36269
2016-02-08T07:55:37+01:00
2016-02-17T12:07:27+01:00
Travailler avec des expressions rationnelles
Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr
<div><p>Les expressions rationnelles sont un outil d’analyse de texte par un ordinateur. Elles permettent de décrire des enchaînements de caractères d’une complexité suffisamment grande pour être réellement utiles, mais suffisamment faible pour être implémentées efficacement. Elles sont d’une importance capitale pour le théoricien des langages comme pour l’<em>UNIX power user</em>.</p>
<p>Dans cette dépêche, nous :</p>
<ul>
<li>décrivons brièvement la notion abstraite d’expression rationnelle et recensons les implémentations les plus courantes sur un système Unix ;</li>
<li>présentons quelques commandes permettant de rechercher des motifs décrits par une expression rationnelle dans un texte, réécrire des fichiers automatiquement ou transformer et analyser des fichiers <em>structurés</em> automatiquement en utilisant des expressions rationnelles ;</li>
<li>montrons comment améliorer votre productivité avec Emacs grâce aux expressions rationnelles.</li>
</ul><p>Dans cette dépêche, nous allons nous pencher sur les expressions rationnelles (souvent nommées abusivement <em>expressions régulières</em> suite à une traduction littérale de <em>regular expression</em>). Elles permettent de représenter formellement un motif de recherche, par exemple : un caractère alphabétique majuscule suivi de quatre caractères minuscules, puis deux chiffres et un point à la fin. Les expressions rationnelles représentent un outil puissant pour qui sait les utiliser à bon escient mais nécessitent une phase d’apprentissage non négligeable. La diversité des moteurs et des syntaxes n’aide pas non plus à leur simplicité, et les confusions entre les différents outils peuvent parfois donner des résultats surprenants.</p></div><ul></ul><div><h2 class="sommaire">Sommaire</h2>
<ul class="toc">
<li><a href="#description-abstraite-et-impl%C3%A9mentations-principales">Description abstraite et implémentations principales</a></li>
<li>
<a href="#les-expressions-rationnelles-posix-basiques">Les expressions rationnelles POSIX basiques</a><ul>
<li><a href="#la-commande-grep">La commande <code>grep</code></a></li>
<li><a href="#utiliser-dans-vi">Utiliser dans vi</a></li>
</ul>
</li>
<li>
<a href="#extension-des-expressions-rationnelles">Extension des expressions rationnelles</a><ul>
<li><a href="#grep-est-mieux-avec--e">grep est mieux avec « -E »</a></li>
<li><a href="#les-classes-de-caract%C3%A8res">Les classes de caractères</a></li>
</ul>
</li>
<li>
<a href="#pour-aller-plus-loin">Pour aller plus loin</a><ul>
<li><a href="#attention-au-glob">Attention au GLOB</a></li>
<li><a href="#outils-pour-tester-vos-expressions-rationnelles">Outils pour tester vos expressions rationnelles</a></li>
<li><a href="#ne-pas-toujours-utiliser-les-expressions-rationnelles">Ne pas toujours utiliser les expressions rationnelles</a></li>
<li><a href="#jouer-avec-les-expressions-rationnelles">Jouer avec les expressions rationnelles</a></li>
<li>
<a href="#un-peu-de-th%C3%A9orie">Un peu de théorie</a><ul>
<li><a href="#les-automates-finis">Les automates finis</a></li>
</ul>
</li>
<li><a href="#litt%C3%A9rature">Littérature</a></li>
</ul>
</li>
</ul><p><img src="//img.linuxfr.org/img/687474703a2f2f786b63642e6c6170696e2e6f72672f7374726970732f786b63642d3230382d65787072657373696f6e732d726567756c69657265732e676966/xkcd-208-expressions-regulieres.gif" alt="Expressions régulières" title="Source : http://xkcd.lapin.org/strips/xkcd-208-expressions-regulieres.gif"><br><em>Source : original en VO <a href="https://xkcd.com/208/">XKCD</a>, traduction en <a href="http://xkcd.lapin.org/index.php?number=208">VF</a></em></p>
<h2 id="description-abstraite-et-implémentations-principales">Description abstraite et implémentations principales</h2>
<p>Les expressions rationnelles sont souvent utilisées comme brique de l’analyse des textes, pour faire de l’analyse lexicale. Elles sont issues des théories mathématiques des langages formels.</p>
<p>Le concept ayant montré sa pertinence, il faut faire face à une richesse des implémentations : <a href="https://fr.wikipedia.org/wiki/POSIX" title="Définition Wikipédia">POSIX</a>, puis chaque Unix à sa version, GNU, FreeBSD, puis Perl et Emacs, pour les plus répandues. Certaines apportent des extensions (sucre syntaxique +, répétitions, groupes, et <em>back tracking</em>).</p>
<p><a href="https://en.wikipedia.org/wiki/Regular_expression#Examples">Wikipédia</a> fournit divers exemples illustratifs. En voici quelques exemples variés :</p>
<ul>
<li>recherche de motif avec <code>grep</code> pour avoir un filtre pour sélectionner des lignes, pour identifier des fichiers, pour sélectionner des journaux système à une certaine date ou pour rechercher dans les pages de manuel, etc. ;</li>
<li>avec <code>sed</code>, transformation de journaux système en format Apache en format tabulaire, transformation de la sortie de Docker, <em>ps</em>, etc. ;</li>
<li>dans <code>Emacs</code>, mettre en valeur un motif dans du code pour une revue ou pour l’édition, extraire des listes d’un fichier avec <em>re-search</em>, etc.</li>
</ul><h2 id="les-expressions-rationnelles-posix-basiques">Les expressions rationnelles POSIX basiques</h2>
<p>Les expressions rationelles <a href="https://fr.wikipedia.org/wiki/POSIX" title="Définition Wikipédia">POSIX</a> génèrent des machines à état fini déterministe. Elles ne sont ainsi pas capables de faire des retours en arrière.</p>
<h3 id="la-commande-grep">La commande <code>grep</code>
</h3>
<p>Le premier usage des expressions rationnelles pour les utilisateurs de systèmes basés sur GNU/Linux ou Unix est en général la commande <code>grep</code>, qui permet de trouver toutes les lignes correspondant à une expression rationnelle. La syntaxe de la commande <code>grep</code> est simplement :<br><code><br>
grep <options> <expression rationnelle> <liste de fichiers><br></code></p>
<p>Pour les exemples ci‐dessous, nous ferons des recherches dans le fichier <em>french</em> d’une <a href="https://fr.wikipedia.org/wiki/Debian" title="Définition Wikipédia">Debian</a> stable (paquet <a href="https://packages.debian.org/search?keywords=wfrench"><em>wfrench</em></a> qui amène le fichier <code>/usr/share/dict/french</code>, [<a href="http://metadata.ftp-master.debian.org/changelogs/main/w/wfrench/wfrench_1.2.3-10_copyright"><em>informations de licence</em></a>]), ce fichier contenant la liste des mots de la langue française à raison d’un mot par ligne.</p>
<p>Dans une expression rationnelle, la première règle est que chaque caractère se représente lui‐même, par exemple l’expression rationnelle « <code>rationnelle</code> » correspond à « toute ligne contenant un <em>r</em>, suivi d’un <em>a</em>, suivi d’un <em>t</em>, suivi d’un <em>i</em>, suivi d’un <em>o</em>, suivi d’un <em>n</em>, suivi d’un autre <em>n</em>, suivi d’un <em>e</em>, suivi d’un <em>l</em>, suivi d’un autre <em>l</em>, suivi d’un <em>e</em>, suivi d’un <em>s</em> » :<br><img src="//img.linuxfr.org/img/687474703a2f2f64656e69732e646f72646f69676e652e65752f646c66702f72656765782f425245312e706e67/BRE1.png" alt="$ grep 'rationnelles' french<br/>
irrationnelles<br/>
opérationnelles<br/>
rationnelles" title="Source : http://denis.dordoigne.eu/dlfp/regex/BRE1.png"></p>
<p>Chaque caractère ne représente pas vraiment lui‐même, il existe des exceptions avec des méta‐caractères qui décrivent autre chose qu’eux‐mêmes. Un des plus utilisés de ces méta‐caractères est le point, qui signifie « un caractère quelconque », par exemple l’expression rationnelle « <code>rationnelle.</code> » correspond à « toute ligne contenant un <em>r</em>, suivi d’un <em>a</em>, suivi d’un <em>t</em>, suivi d’un <em>i</em>, suivi d’un <em>o</em>, suivi d’un <em>n</em>, suivi d’un autre <em>n</em>, suivi d’un <em>e</em>, suivi d’un <em>l</em>, suivi d’un autre <em>l</em>, suivi d’un <em>e</em>, suivi d’un caractère quelconque » :<br><img src="//img.linuxfr.org/img/687474703a2f2f64656e69732e646f72646f69676e652e65752f646c66702f72656765782f627265322e706e67/bre2.png" alt="$ grep 'rationnelle.' french<br/>
irrationnelles<br/>
opérationnelles<br/>
irrationnellement<br/>
rationnelles" title="Source : http://denis.dordoigne.eu/dlfp/regex/bre2.png"></p>
<p>Le problème des méta‐caractères est qu’on peut vouloir chercher du texte les contenant. Par exemple, dans notre dictionnaire, il y a des abréviations se terminant par un point. Pour qu’un méta‐caractère ne soit pas interprété, il faut le précéder d’une contre‐oblique « \ », par exemple « \. » représente le caractère point. On peut alors s’amuser à chercher les abréviations d’au moins six caractères, en les décrivant comme « un caractère quelconque, suivi d’un autre caractère quelconque, suivi d’un troisième caractère quelconque, suivi d’un quatrième caractère quelconque, suivi d’un cinquième caractère quelconque, suivi d’un sixième caractère quelconque, suivi d’un point » :<br><img src="//img.linuxfr.org/img/687474703a2f2f64656e69732e646f72646f69676e652e65752f646c66702f72656765782f425245332e706e67/BRE3.png" alt="$ grep '......\.' french<br/>
arrond.<br/>
c.‐à‐d." title="Source : http://denis.dordoigne.eu/dlfp/regex/BRE3.png"><br>
On remarquera que le point lui‐même est un caractère quelconque.</p>
<p>Un autre méta‐caractère utile est le crochet, qui permet de décrire un caractère pouvant correspondre à plusieurs valeurs, par exemple une voyelle non accentuée peut être représentée par « <code>[aeiouy]</code> » (qu’on peut lire comme « n’importe quel caractère étant soit un <em>a</em>, soit un <em>e</em>, soit un <em>i</em>, soit un <em>u</em>, soit un <em>y</em> »). Par exemple, si vous voulez briller en société en citant des mots comportant six voyelles non accentuées à la suite :<br><img src="//img.linuxfr.org/img/687474703a2f2f64656e69732e646f72646f69676e652e65752f646c66702f72656765782f425245342e706e67/BRE4.png" alt="$ grep '[aeiouy][aeiouy][aeiouy][aeiouy][aeiouy][aeiouy]' french<br/>
rougeoyaient<br/>
youyou<br/>
youyous" title="Source : http://denis.dordoigne.eu/dlfp/regex/BRE4.png"></p>
<p>Deux méta‐caractères particuliers sont utiles entre crochets :</p>
<ul>
<li>le tiret situé entre deux caractères permet de définir une liste de caractères qui se suivent, par exemple « <code>[a-f]</code> » définit « soit un <em>a</em>, soit un <em>b</em>, soit un <em>c</em>, soit un <em>d</em>, soit un <em>e</em>, soit un <em>f</em> » ;</li>
<li>l’accent circonflexe situé au début permet de définir une exclusion de caractères, par exemple « <code>[\^aeiouy]</code> » définit « un quelconque caractère qui ne soit ni un <em>a</em>, ni un <em>e</em>, ni un <em>i</em>, ni un <em>o</em>, ni un <em>u</em>, ni un <em>y</em> »).
Ces deux méta‐caractères sont cumulables, par exemple « <code>[\^a-z]</code> » définit « un quelconque caractère qui ne soit pas une lettre minuscule non accentuée », ce qui peut nous permettre de trouver tous les mots qui ont à la suite deux caractères qui ne sont pas des lettres :
<img src="//img.linuxfr.org/img/687474703a2f2f64656e69732e646f72646f69676e652e65752f646c66702f72656765782f425245352e706e67/BRE5.png" alt="$ grep '[^a-z][^a-z]' french
c.‐à‐d.
ch.-l." title="Source : http://denis.dordoigne.eu/dlfp/regex/BRE5.png">
</li>
</ul><p>On peut économiser les copier‐coller lorsque l’on veut chercher plusieurs fois la même information, en utilisant le symbole « <code>\{min,max\}</code> » qui permet d'indiquer que l’on cherche la présence d’un caractère successivement entre <em>min</em> et <em>max</em> fois, par exemple si vous cherchez les mots contenant deux <em>q</em> séparés par 5 à 7 lettres [<sup>1] :</sup><br><img src="//img.linuxfr.org/img/687474703a2f2f64656e69732e646f72646f69676e652e65752f646c66702f72656765782f425245362e706e67/BRE6.png" alt="$ grep 'q[a-z]\{5,7\}q' french <br/>
quantique<br/>
quantiques<br/>
quelconque<br/>
quelconques<br/>
quiconque<br/>
quiproquo<br/>
quiproquos<br/>
squelettique<br/>
squelettiques" title="Source : http://denis.dordoigne.eu/dlfp/regex/BRE6.png"></p>
<p>Il est possible avec certaines versions de <em>grep</em> de spécifier un seul chiffre entre accolades :</p>
<ul>
<li>si l’on cherche exactement <em>x</em> occurrences, on indique : « <code>\{x\}</code> » ;</li>
<li>si l’on cherche de 0 à <em>x</em> occurrences, on indique : « <code>\{,x\}</code> » ;</li>
<li>si l’on cherche au moins <em>x</em> occurrences, on indique : « <code>\{x,\}</code> ».
Ainsi, on pourrait donc abréger la recherche des mots contenant 6 voyelles non accentuées ainsi :
<img src="//img.linuxfr.org/img/687474703a2f2f64656e69732e646f72646f69676e652e65752f646c66702f72656765782f425245372e706e67/BRE7.png" alt="$ grep '[aeiouy]\{6\}' french
rougeoyaient
youyou
youyous" title="Source : http://denis.dordoigne.eu/dlfp/regex/BRE7.png">
</li>
</ul><p>Si l’on veut répéter plusieurs caractères au lieu d’un seul, il faut encadrer la recherche avec des « <code>\( \)</code> ». Par exemple, si vous bloquez dans une grille de mots croisés sur la définition « mot contenant sept fois à la suite une consonne suivie d’une voyelle » :<br><img src="//img.linuxfr.org/img/687474703a2f2f64656e69732e646f72646f69676e652e65752f646c66702f72656765782f425245392e706e67/BRE9.png" alt="$ grep '\([^aeiouy][aeiouy]\)\{7\}' french <br/>
remilitarisation<br/>
" title="Source : http://denis.dordoigne.eu/dlfp/regex/BRE9.png"></p>
<p>Le contenu trouvé à partir d’une expression entre parenthèses est dit « capturé », cela signifie qu’il est gardé en mémoire et peut être réutilisé dans l’expression rationnelle. La contenu capturé est accessible en utilisant « <code>\1</code> », « <code>\2</code> », « <code>\3</code> », etc. (en général, on ne peut pas dépasser <code>\9</code>). Le numéro de capture est défini en comptant le nombre de parenthèses ouvrantes précédant l’expression capturée. Cela permet par exemple de lister les mots contenant un palindrome de quatre lettres :<br><img src="//img.linuxfr.org/img/687474703a2f2f64656e69732e646f72646f69676e652e65752f646c66702f72656765782f42524531302e706e67/BRE10.png" alt="$ grep '\(.\)\(.\)\(.\)\(.\)\4\3\2\1' french <br/>
caressera<br/>
caresserai<br/>
caresseraient<br/>
caresserais<br/>
caresserait<br/>
caresseras<br/>
paressera<br/>
paresserai<br/>
paresseraient<br/>
paresserais<br/>
paresserait<br/>
paresseras<br/>
querellerez" title="Source : http://denis.dordoigne.eu/dlfp/regex/BRE10.png"></p>
<p>On peut encore affiner les recherches en utilisant les ancres, qui permettent de situer où se situe une expression rationnelle dans la ligne :</p>
<ul>
<li>le dollar, lorsqu’il est situé à la fin de l’expression rationnelle, représente la fin de la ligne ;</li>
<li>l’accent circonflexe, lorsqu’il est situé au début de l’expression rationnelle, représente le début de la ligne.</li>
</ul><p>On peut cumuler les deux ancres dans la même expression, par exemple si l’on veut chercher les vrais palindromes de quatre lettres :<br><img src="//img.linuxfr.org/img/687474703a2f2f64656e69732e646f72646f69676e652e65752f646c66702f72656765782f42524531312e706e67/BRE11.png" alt="`{mathjax} grep '^\(.\)\(.\)\2\1`' french <br/>
alla<br/>
elle<br/>
erre<br/>
esse" title="Source : http://denis.dordoigne.eu/dlfp/regex/BRE11.png"></p>
<p>Pour en terminer avec les expressions rationnelles POSIX basiques, il ne reste plus qu’un méta‐caractère à présenter, qui est l’astérisque. Ce caractère est équivalent à « <code>\{0,\}</code> » :<br><img src="//img.linuxfr.org/img/687474703a2f2f64656e69732e646f72646f69676e652e65752f646c66702f72656765782f42524531322e706e67/BRE12.png" alt="`{mathjax} grep '^d.*ouilles`' french <br/>
débrouilles<br/>
dépouilles<br/>
douilles" title="Source : http://denis.dordoigne.eu/dlfp/regex/BRE12.png"></p>
<h3 id="utiliser-dans-vi">Utiliser dans vi</h3>
<p><a href="http://vimregex.com">VimRegex</a> détaille largement le sujet.</p>
<h2 id="extension-des-expressions-rationnelles">Extension des expressions rationnelles</h2>
<p>Les extensions rationnelles basiques étant peu lisibles, la norme POSIX a évolué pour intégrer les expressions rationnelles étendues, aussi appelées « ERE ».</p>
<h3 id="grep-est-mieux-avec--e">grep est mieux avec « -E »</h3>
<p>Les versions récentes de <code>grep</code> permettent d’utiliser les expressions rationnelles étendues avec l’option <code>-E</code>. Si vous ajoutez l’option <code>-E</code> à <code>grep</code>, vous devez modifier votre expression rationnelle ainsi :</p>
<ul>
<li>
<code>\{</code> et <code>\}</code> deviennent <code>{</code> et <code>}</code> ;</li>
<li>
<code>\(</code> et <code>\)</code> deviennent <code>(</code> et <code>)</code> ;</li>
<li>tous les autres méta‐caractères (« <code>.</code> », « <code>[</code> », « <code>]</code> », « <code>-</code> », « <code>^</code> », « <code>$</code> », « <code>*</code> », « <code>\1</code> », etc.) sont inchangés.</li>
</ul><p>Outre cette suppression des contre‐obliques superflus, les expressions rationnelles étendues apportent trois nouveaux méta‐caractères. Le premier est « <code>?</code> » qui est un synonyme de « <code>{0,1}</code> », qui permet par exemple de chercher les palindromes de 4 ou 6 lettres avec une seule expression :<br><img src="//img.linuxfr.org/img/687474703a2f2f64656e69732e646f72646f69676e652e65752f646c66702f72656765782f455245312e706e67/ERE1.png" alt="<br/>
`{mathjax} grep -E '^(.)(.)((.)\4)?\2\1`' french <br/>
alla<br/>
elle<br/>
erre<br/>
esse<br/>
selles<br/>
serres" title="Source : http://denis.dordoigne.eu/dlfp/regex/ERE1.png"></p>
<p>On dispose aussi de « <code>+</code> » qui est un synonyme de « <code>{1,}</code> » :<br><img src="//img.linuxfr.org/img/687474703a2f2f64656e69732e646f72646f69676e652e65752f646c66702f72656765782f455245322e706e67/ERE2.png" alt="`{mathjax} grep -E '^cré+e`' french <br/>
crée<br/>
créée<br/>
" title="Source : http://denis.dordoigne.eu/dlfp/regex/ERE2.png"></p>
<p>Enfin, le dernier méta‐caractère spécifique aux expressions rationnelles étendues est le « <code>|</code> » qui permet de séparer plusieurs options :<br><img src="//img.linuxfr.org/img/687474703a2f2f64656e69732e646f72646f69676e652e65752f646c66702f72656765782f455245332e706e67/ERE3.png" alt="`{mathjax} grep -E '^(gr|f|citr)ouille`' french <br/>
citrouille<br/>
fouille<br/>
grouille" title="Source : http://denis.dordoigne.eu/dlfp/regex/ERE3.png"></p>
<h3 id="les-classes-de-caractères">Les classes de caractères</h3>
<p>POSIX prévoit des classes de caractère, qui sont des notations spécifiques entre crochets. À noter que les classes de caractères sont aussi bien gérées par les expressions rationnelles basiques qu’étendues (il n’y a donc pas besoin d’utiliser l’option <code>-E</code> pour en bénéficier), mais il existe des implémentations d’expressions rationnelles basiques non compatibles POSIX qui ne les acceptent pas.</p>
<p>Les classes de caractères sont des mots ou abréviations en anglais désignant ce à quoi ils correspondent et encadrés par « <code>[:</code> » et « <code>:]</code> » :</p>
<ul>
<li>
<code>[:digit:]</code> : désigne un chiffre décimal (équivalent à <code>[0-9]</code>) ;</li>
<li>
<code>[:lower:]</code> : désigne une lettre minuscule (équivalent à <code>[a-z]</code>) ;</li>
<li>
<code>[:upper:]</code> : désigne une lettre majuscule (équivalent à <code>[A-Z]</code>) ;</li>
<li>
<code>[:alpha:]</code> : désigne une lettre minuscule ou majuscule (équivalent à <code>[A-Za-z]</code>) ;</li>
<li>
<code>[:alnum:]</code> : désigne une lettre minuscule ou majuscule ou un chiffre (équivalent à <code>[A-Za-z0-9]</code>) ;</li>
<li>
<code>[:xdigit:]</code> : désigne un chiffre hexadécimal (équivalent à [0-9a-fA-F]) ;</li>
<li>
<code>[:space:]</code> : désigne un caractère d’espacement (espace, tabulation, retour chariot, etc.) ;</li>
<li>
<code>[:blank:]</code> : désigne un espace ou une tabulation horizontale (à ne pas confondre avec <code>[:space:]</code>) ;</li>
<li>
<code>[:punct:]</code> : désigne à un crochet ou un caractère de la classe suivante : <code>['!"#$%&()*+,./:;<=>?@\^_</code>{|}~-]` ;</li>
<li>
<code>[:cntrl:]</code> : désigne un <a href="https://fr.wikipedia.org/wiki/caract%C3%A8re%20de%20contr%C3%B4le" title="Définition Wikipédia">caractère de contrôle</a> ;</li>
<li>
<code>[:print:]</code> : désigne un caractère affichable (ainsi qu’une espace), cette classe est à peu près le contraire de <code>[:cntrl:]</code> ;</li>
<li>
<code>[:graph:]</code> : désigne l’ensemble des caractères visibles, sauf les espaces, les caractères de contrôle, etc. (équivalent à <code>[\x21-\x7E]</code>).</li>
</ul><h2 id="pour-aller-plus-loin">Pour aller plus loin</h2>
<h3 id="attention-au-glob">Attention au GLOB</h3>
<p>Dans les exemples précédents, il était important d’utiliser de simples apostrophes pour éviter l’interprétation de caractères spéciaux par le <em>Shell</em>.</p>
<h3 id="outils-pour-tester-vos-expressions-rationnelles">Outils pour tester vos expressions rationnelles</h3>
<p>Plusieurs outils s’offrent à vous pour tester et triturer dans tous les sens vos expressions rationnelles, comme par exemple le site <a href="http://regexpal.com/"><em>Regex Pal</em></a>, qui propose notamment de la coloration syntaxique et se veut « temps réel » dans les modifications, ou <a href="https://regex101.com"><em>regex101</em></a> qui permet de tester des expressions rationnelles Python, JavaScript ou <a href="https://fr.wikipedia.org/wiki/PCRE" title="Perl Compatible Regular Expression — Expressions rationnelles compatibles Perl">PCRE</a>.</p>
<h3 id="ne-pas-toujours-utiliser-les-expressions-rationnelles">Ne pas toujours utiliser les expressions rationnelles</h3>
<p>Les expressions rationnelles ne sont par exemple pas l’outil idéal pour analyser du XML ou du HTML.</p>
<h3 id="jouer-avec-les-expressions-rationnelles">Jouer avec les expressions rationnelles</h3>
<p>Voir la dépêche <a href="//linuxfr.org/news/regexcrossword-un-subtil-melange-de-sudoku-et-de-mots-croises-a-la-sauce-regex"><em>Regexcrossword : un subtil mélange de sudoku et de mots croisés, à la sauce Regex</em></a>, ainsi que <a href="http://www.i-programmer.info/news/144-graphics-and-games/5450-can-you-do-the-regular-expression-crossword.html">la chasse au trésor du MIT en 2014</a>, etc.</p>
<h3 id="un-peu-de-théorie">Un peu de théorie</h3>
<h4 id="les-automates-finis">Les automates finis</h4>
<p>La base théorique des expressions rationnelles se trouve dans la théorie des langages. Elles permettent notamment de décrire les <a href="https://fr.wikipedia.org/wiki/Langage_rationnel">langages rationnels</a>. Elles sont fortement liées aux <a href="https://fr.wikipedia.org/wiki/Automate_fini">automates finis</a>.</p>
<p>Pour illustrer le parallèle nous allons utiliser les caractères et les quantificateurs de base :</p>
<ul>
<li>
<code>a</code> qui permet de reconnaître la lettre <code>a</code> ;</li>
<li>
<code>?</code> qui permet de définir un groupe optionnel ;</li>
<li>
<code>*</code> qui permet de définir un groupe se répétant zéro fois ou plus ;</li>
<li>
<code>+</code> qui permet de définir un groupe se répétant une fois ou plus.</li>
</ul><h3 id="littérature">Littérature</h3>
<ul>
<li>une des ressources en ligne indispensables sur les moteurs d’expressions rationnelles se trouve sur le site de Russ Cox : <a href="https://swtch.com/%7Ersc/regexp/">https://swtch.com/~rsc/regexp/</a> ;</li>
<li>un vieil <a href="http://perl.plover.com/Regex/article.html">article de Mark‐Jason Dominus</a> explique le fonctionnement des expressions rationnelles et leur application dans Perl ;</li>
<li>une implémentation expliquée d’un moteur d’expressions rationnelles est disponible dans un <a href="http://ezekiel.vancouver.wsu.edu/%7Ecs317/archive/projects/grep/grep.pdf">cours de l’Université de Vancouver</a>.</li>
</ul><p><em>[<sup>1</sup>] Avec ça vous allez vraiment briller en société, il faudra juste trouver un moyen d’intégrer ça dans la conversation.</em></p></div><div><a href="https://linuxfr.org/news/travailler-avec-des-expressions-rationnelles.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/105209/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/news/travailler-avec-des-expressions-rationnelles#comments">ouvrir dans le navigateur</a>
</p>
Denis Dordoigne
Davy Defaud
Benoît Sibaud
Nÿco
Lucas
palm123
esdeem
Michaël
Stéphane Aulery
Xavier Teyssier
Kwiknclean
Jiel
Nicolas Casanova
Trollgouin
BAud
ranDom
Ontologia
anaseto
Jiehong
https://linuxfr.org/nodes/105209/comments.atom
tag:linuxfr.org,2005:Post/36427
2016-01-31T14:13:26+01:00
2016-01-31T14:45:55+01:00
[Résolu] Erreur immonde avec boost/regex
<p>Hello,</p>
<p>J'essaye d'écrire un programme pour classer mes milliers de photos dans des dossiers, selon leur date de prise de vue.</p>
<p>Une grande partie est constituée de captures d'écran ou de photos échangées par Facebook/MMS/autre, et les données EXIF ne contiennent donc pas cette date. Les dates de création et de modification des fichiers ne correspondent pas non plus.</p>
<p>En revanche, beaucoup de fichiers ont leur date de prise de vue dans leur nom, de la forme : <code>IMG_20151226_124053.jpg</code> (pris le 26/12/2015 à 12:40:53). J'ai donc écrit une <a href="https://fr.wikipedia.org/wiki/Expression_rationnelle">expression rationnelle</a> pour extraire la date de ce genre de nom de fichier.</p>
<p>J'utilise C++ et la bibliothèque <code>boost</code> pour appliquer cette expression rationnelle aux noms de fichier. Voici le code qui doit extraire la date :</p>
<pre><code class="C++"><span class="k">const</span> <span class="n">string</span> <span class="n">FILENAME_DATE_REGEX</span> <span class="o">=</span> <span class="s">"[0-9A-Za-z]+_(?P<year>20[0-9]{2}).?(?P<month>(?:0[1-9])|(?:1[0-2])).?(?P<day>(?:[012][1-9])|(?:3[01])).?(?P<hour>(?:[01][0-9])|(?:2[0-4])).?(?P<minute>(?:[0-5][0-9])|(?:60)).?(?P<second>(?:[0-5][0-9])|(?:60))</span><span class="se">\\</span><span class="s">.(?P<extension>(?:jpe?g)|(?:png))"</span><span class="p">;</span>
<span class="n">boost</span><span class="o">::</span><span class="n">regex</span> <span class="n">ex</span><span class="p">(</span><span class="n">FILENAME_DATE_REGEX</span><span class="p">);</span>
<span class="n">boost</span><span class="o">::</span><span class="n">match_results</span><span class="o"><</span><span class="n">string</span><span class="o">::</span><span class="n">const_iterator</span><span class="o">></span> <span class="n">result</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">boost</span><span class="o">::</span><span class="n">regex_match</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">result</span><span class="p">,</span> <span class="n">ex</span><span class="p">))</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o"><</span><span class="n">result</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="n">cout</span> <span class="o"><<</span> <span class="n">result</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o"><<</span> <span class="sc">'\n'</span><span class="p">;</span>
<span class="p">}</span></code></pre>
<p>Et voici l'erreur que le compilateur me renvoie à cause de ce code :</p>
<pre><code>/tmp/ccUv9HUa.o: dans la fonction « bool boost::regex_match<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > >, char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >(__gnu_cxx::__normal_iterator<char const*, std::string>, __gnu_cxx::__normal_iterator<char const*, std::string>, boost::match_results<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > > >&, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags) »:
sortimgs.cpp:(.text._ZN5boost11regex_matchIN9__gnu_cxx17__normal_iteratorIPKcSsEESaINS_9sub_matchIS5_EEEcNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEEEbT_SD_RNS_13match_resultsISD_T0_EERKNS_11basic_regexIT1_T2_EENS_15regex_constants12_match_flagsE[_ZN5boost11regex_matchIN9__gnu_cxx17__normal_iteratorIPKcSsEESaINS_9sub_matchIS5_EEEcNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEEEbT_SD_RNS_13match_resultsISD_T0_EERKNS_11basic_regexIT1_T2_EENS_15regex_constants12_match_flagsE]+0x80): référence indéfinie vers « boost::re_detail::perl_matcher<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::match() »
/tmp/ccUv9HUa.o: dans la fonction « boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::assign(char const*, char const*, unsigned int) »:
sortimgs.cpp:(.text._ZN5boost11basic_regexIcNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEE6assignEPKcS7_j[_ZN5boost11basic_regexIcNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEE6assignEPKcS7_j]+0x2a): référence indéfinie vers « boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::do_assign(char const*, char const*, unsigned int) »
/tmp/ccUv9HUa.o: dans la fonction « boost::re_detail::perl_matcher<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::perl_matcher(__gnu_cxx::__normal_iterator<char const*, std::string>, __gnu_cxx::__normal_iterator<char const*, std::string>, boost::match_results<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > > >&, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags, __gnu_cxx::__normal_iterator<char const*, std::string>) »:
sortimgs.cpp:(.text._ZN5boost9re_detail12perl_matcherIN9__gnu_cxx17__normal_iteratorIPKcSsEESaINS_9sub_matchIS6_EEENS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEEC2ES6_S6_RNS_13match_resultsIS6_S9_EERKNS_11basic_regexIcSD_EENS_15regex_constants12_match_flagsES6_[_ZN5boost9re_detail12perl_matcherIN9__gnu_cxx17__normal_iteratorIPKcSsEESaINS_9sub_matchIS6_EEENS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEEC5ES6_S6_RNS_13match_resultsIS6_S9_EERKNS_11basic_regexIcSD_EENS_15regex_constants12_match_flagsES6_]+0x116): référence indéfinie vers « boost::re_detail::perl_matcher<__gnu_cxx::__normal_iterator<char const*, std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, std::string> > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::construct_init(boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags) »
collect2: error: ld returned 1 exit status
</code></pre>
<p>J'adorerais pouvoir faire plus clair, mais ce message d'erreur me dépasse. Que suis-je censé faire de ça ? Où est l'erreur ?</p>
<p>Édit : j'ai testé avec une expression rationnelle plus simple et le message d'erreur ne change pas. De plus, celle-ci avait fonctionné dans un programme en Python. L'erreur n'est donc pas dans cette expression.</p><div><a href="https://linuxfr.org/forums/programmation-c/posts/resolu-erreur-immonde-avec-boost-regex.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/108048/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/forums/programmation-c/posts/resolu-erreur-immonde-avec-boost-regex#comments">ouvrir dans le navigateur</a>
</p>
UnGens
https://linuxfr.org/nodes/108048/comments.atom
tag:linuxfr.org,2005:Diary/35842
2015-05-07T17:05:41+02:00
2015-05-08T19:40:06+02:00
Vivent les journaux binaires !
Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr
<p>Bonjour cher 'nal,</p>
<p>Comme toi, j'aime systemd, j'aime les jounaux binaires, j'aime la manière facile d'interroger le journal binaire, et j'aime que la machine travaille pour moi.</p>
<p>Faire des regex, c'est long, pas lisible, et chiant. La machine peut faire ça pour moi.</p>
<p>Chercher un symbole avec less, c'est pas pratique quand y'a des doublons.</p>
<p>grep n'est pas pratique sur un grand fichier, et multiplier les fichiers journaux c'est franchement pas génial pour avoir une organisation de ces fichiers bien rangée.</p>
<p>Oh miracle cher 'nal ! Quelqu'un pense comme moi et explique tout ceci et bien plus de manière bien plus détaillée et argumentée que je ne pourrais le faire. Quelqu'un qui utilise des journaux au format binaire depuis bien avant systemd-journald, et sans l'aide de systemd-journald.</p>
<p>Et comme une traduction pourrait dénaturer le propos, je ne propose que les liens :<br><a href="http://asylum.madhouse-project.org/blog/2015/05/05/grepping-logs-is-terrible/">Grepping logs is terrible</a></p>
<p><a href="http://asylum.madhouse-project.org/blog/2015/05/07/grepping-logs-is-still-terrible/">Grepping logs is still terrible</a></p>
<p>Bonne lecture !</p><div><a href="https://linuxfr.org/users/xcomcmdr/journaux/vivent-les-journaux-binaires.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/105691/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/xcomcmdr/journaux/vivent-les-journaux-binaires#comments">ouvrir dans le navigateur</a>
</p>
xcomcmdr
https://linuxfr.org/nodes/105691/comments.atom
tag:linuxfr.org,2005:Diary/35244
2014-09-13T14:20:59+02:00
2014-09-13T14:20:59+02:00
Journal Bookmark #1
Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr
<p><a href="http://felixniklas.com/dimensions/">Dimensions</a>, une extension Chrome permettant de mesurer, en pixels, tous les éléments d'une page web.</p>
<p><a href="http://lists.gnu.org/archive/html/coreutils/2014-08/msg00012.html">Un expérience testant les limites de la commandes <code>cp</code></a> : que ce passe t-il lorsqu'on copie 432 millions de fichiers totalisant 39 To ?</p>
<p><a href="http://www.haskellforall.com/2014/09/morte-intermediate-language-for-super.html">Morte</a>, une expérience pour faire une sorte de templating (comme ceux de C++) automatique : il regarde ce qui est calculable en fonction des informations dont il dispose dans le code et précompile</p>
<p><a href="http://www.algomation.com/">Algomation</a>, un site pour visualiser des algorithmes (sur les graphes par exemple) visuellement.</p>
<p><a href="http://rcoh.svbtle.com/no-magic-regular-expressions">Un moteur de regexp en Scala en moins de 200 lignes</a>. Non, il n'est pas PCRE, faut pas pousser non plus :-)</p>
<p>Pourquoi ce journal ?<br>
Constatant que les contenus de linuxfr sont un peu faible techniquement, et qu'on est plus au courant, par ce site, de ce qui se passe sur le front "développement, librairies, etc…", j'ai fait l'expérience suivante : chercher un contenu intéressant sur les 3 premières pages du site.<br>
Résultat : rien.<br>
J'ai ensuite essayé HackerNews, les liens plus haut sont le résultat de ce que je peux trouver d'intéressant dans les deux premières pages d'HackerNews.</p>
<p>Le problème, je pense, est que sur ce site, mis à part que les intégristes sont sur-représentés - probablement à cause d'un dogmatisme bien typique de la franchouillardise -, on dénigre quiconque propose des contenus décrivant en quelques mot une chose ou une autre : Répétant inconsciemment l'exercice de la dissertation au lycée, on nous demande blablater un minimum.</p>
<p>Être synthétique est infamant.</p>
<p>Résultat, personne n'ose poster des news très courtes, et ceux qui le font se prennent un "boooouhhhhhh : journal bookmark, pas bien !!!"</p><div><a href="https://linuxfr.org/users/montaigne/journaux/journal-bookmark-1.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/103277/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/montaigne/journaux/journal-bookmark-1#comments">ouvrir dans le navigateur</a>
</p>
Ontologia
https://linuxfr.org/nodes/103277/comments.atom