Page 1 sur 1
Regex pour inserer du texte dans un fichier
Posté : sam. 24 juin 2017 15:34
par Tlem
Bonjour. Exceptionnellement, je fait une demande d'aide afin d'améliorer un code.
Le principe :
Lire le fichier C:\Program Files (x86)\AutoIt3\SciTE\Properties\au3.properties
Rajouter une section "command" juste après la dernière section "command" disponible.
Actuellement, mon code fonctionne, mais je passe par la conversion du fichier en tableau, puis par la lecture ligne par ligne pour trouver l'endroit ou je dois rajouter ma section.
Bien que cette méthode soit fonctionnelle, j'aimerais l'améliorer en utilisant les expressions régulières et comme je ne suis pas expert en la matière, je demande un petit coup de main. ^^
La requête :
Utiliser une (ou deux) expressions régulières pour découper le contenu du fichier en 2 parties.
La première partie va du début du fichier, jusqu'à la dernière ligne de la dernière section.
La deuxième partie doit contenir le reste du fichier.
Les éléments et contraintes :
- Bien que celui-ci n'est pas sensé être modifié, je ne souhaite pas me baser sur le texte de la première ligne (# SciTE settings for AutoIt v3) et démarrer la capture à partir du début du texte.
- Je ne souhaite pas me baser sur les lignes descriptives des sections (# xx description de la section).
- Je ne souhaite pas prendre en considération les éventuelles lignes qui pourraient être en commentaires (tel que #command.subsystem.xx.$(au3)=1).
- Je connais le numéro de la dernière section existante.
Je souhaiterais donc a partir du contenu du fichier "au3.properties" et en utilisant une (ou deux) expressions régulière mettre dans une variable, tout ce qu'il y a entre le début du texte, jusqu'à la dernière ligne de la forme "command.xx" ou "command.*.xx" sachant que xx est un nombre connu et que entre "command." et "xx" il peux y avoir (ou pas) un certain nombre de caractères.
Et dans la seconde variable le reste du texte.
Voici un extrait du fichier "au3.properties" qui montre comment sont formées certines sections "command" :
Code : Tout sélectionner
# 12 lookfar's Koda FormDesigner
command.12.$(au3)="$(SciteDefaultHome)\Koda\FD.exe" /Scite
command.subsystem.12.$(au3)=1
command.name.12.$(au3)=Koda(FormDesigner)
command.shortcut.12.$(au3)=Alt+m
command.save.before.12.$(au3)=2
command.replace.selection.12.$(au3)=1
command.quiet.12.$(au3)=1
# 14 Jos's SciTeConfig
command.14.$(au3)="$(SciteDefaultHome)\..\AutoIt3.exe" "$(SciteDefaultHome)\SciteConfig\SciteConfig.au3"
command.name.14.$(au3)=SciTe Config
command.shortcut.14.$(au3)=Ctrl+1
command.subsystem.14.$(au3)=2
command.save.before.14.$(au3)=2
command.replace.selection.14.$(au3)=0
command.quiet.14.$(au3)=1
# 15 Update Source in Version repository
command.15.*="$(SciteDefaultHome)\..\AutoIt3.exe" "$(SciteDefaultHome)\AutoIt3Wrapper\AutoIt3Wrapper.au3" /in "$(FilePath)" /Versioning_Commit
command.name.15.*=Version Update Source
command.save.before.15.*=1
command.shortcut.15.*=F12
# 18 Jump to Func quickly
command.name.18.$(au3)=Jump to Function Prod
command.mode.18.$(au3)=subsystem:lua,savebefore:yes
command.shortcut.18.$(au3)=Ctrl+J
command.18.$(au3)=InvokeTool AutoItGotoDefinition.GotoDefinition
Merci d'avance.
Re: Regex pour inserer du texte dans un fichier
Posté : sam. 24 juin 2017 16:57
par orax
Code : Tout sélectionner
#include <StringConstants.au3>
$a = StringRegExp(FileRead("C:\Program Files (x86)\AutoIt3\SciTE\Properties\au3.properties"), "(?ms)(.*^\h*command\.(?:\w+\.)*(\d+)\.\N+)(.*)", $STR_REGEXPARRAYGLOBALMATCH)
;~ FileWrite("_temp0.tmp.txt", $a[0]) ; début jusqu'à la dernière commande qui contient un nombre
ConsoleWrite("Dernière commande = " & $a[1] & @CRLF)
;~ FileWrite("_temp2.tmp.txt", $a[2]) ; fin du fichier (peut être vide)
;~ FileWrite("_temp.tmp.txt", $a[0] & $a[2]) ; ce fichier doit être identique à au3.properties
On peut remplacer
(\d+)
par
\d+
s'il n'y a pas besoin de récupérer le numéro de la dernière commande, mais ça pourrait être utile pour vérifier que le numéro récupéré par l'expression régulière est bien identique au numéro connu.
On pourrait aussi faire
"(?ms)(.*^\h*command\.(?:\w+\.)*" & xx & "\.\N+)(.*)"
où
xx correspond au nombre connu.
Les commandes qui ne contiennent pas un nombre, comme
command.help.$(au3)=$(SciteDefaultHome)\..\Autoit3Help.exe "$(CurrentWord)"
, ne sont pas détectées.
Re: Regex pour inserer du texte dans un fichier
Posté : sam. 24 juin 2017 21:51
par Tlem
Hummm, comment dire ...
Ben c'est parfait, cela m'évite une Regex qui récupère le numéro de la dernière section "command", puis 2 traitements a base de boucle While pour lire l'emplacement de la dernière ligne de la dernière section "command" ...
Comme d'ab, merci beaucoup Adrien.
Re: Regex pour inserer du texte dans un fichier
Posté : sam. 24 juin 2017 23:42
par mikell
Tlem a écrit : ↑sam. 24 juin 2017 15:34Rajouter une section "command" juste après la dernière section "command" disponible.
Si c'est pour faire une insertion, pas besoin de découper en sous-fichiers, tu peux le faire directement
Re: Regex pour inserer du texte dans un fichier
Posté : dim. 25 juin 2017 00:18
par Tlem
Bonsoir Michel, très intéressant aussi.
Cette méthode évite de passer par la concaténation des deux captures faites dans le code d'Adrien, mais m'oblige à conserver la récupération du numéro par une autre Regex.
L'avantage du code d'Adrien, c'est que la ligne me permet en une seule fois de récupérer le début du texte, le numéro de la dernière section et la fin du texte directement dans un tableau.
J'ai juste à "construire" la nouvelle section avec le numéro + 1 et à concaténer le tout.
Dans ton cas, on peut aussi récupérer le numéro ("$2") mais comment ajouter 1 ? et puis il faudrait construite la nouvelle section directement dans l'expression.
Même si cela limite les lignes de codes, cela ne rend pas celui-ci plus simple à lire ...
En tout cas, merci pour ce code vraiment sympa.
Re: Regex pour inserer du texte dans un fichier
Posté : dim. 25 juin 2017 10:30
par mikell
Tlem a écrit : ↑dim. 25 juin 2017 00:18comment ajouter 1 ?
(...)
Même si cela limite les lignes de codes, cela ne rend pas celui-ci plus simple à lire ...
Si tu veux de la simplicité vaut mieux éviter les regex - quoique, ça peut se discuter ^^
Re: Regex pour inserer du texte dans un fichier
Posté : dim. 25 juin 2017 11:59
par Tlem
Bonjour Michel, magnifique démonstration de la maitrise de l'utilisation des expressions régulières.
Bravo
Si tu veux de la simplicité vaut mieux éviter les regex - quoique, ça peut se discuter ^^
Le but est de rendre le code plus simple en exécution, mais tout en gardant une certaine simplicité de lecture. ^^
Dans le cas présent, je remplace environs 30 lignes de code par une seule ligne ...
Même si le pattern semblera incompréhensible pour un novice (ou à moi même dans 6 mois), les commentaires feront le nécessaire.

Re: Regex pour inserer du texte dans un fichier
Posté : dim. 25 juin 2017 12:50
par mikell
Là tu auras du mal à trouver plus simple en exécution... fichier in > et hop > fichier out
Pour la simplicité de lecture, l'intérêt c'est que la nouvelle section (avec comme seul paramètre le numéro) peut être importée depuis une fonction (comme dans le script) ou depuis n'importe où (un .txt, etc)
Pour le regex bin c'est orax qui a fait le boulot à 95% . Laisser bosser les autres c'est cool
Y fallait commenter ? j'ai pensé que s'il devait y avoir des commentaires, en tant qu'utilisateur il valait mieux que ce soit toi qui t'en occupes... sinon c'est la faute à orax

Re: Regex pour inserer du texte dans un fichier
Posté : dim. 25 juin 2017 16:02
par jchd
Pour les commentaires d'une regexp, une bonne solution qui sauvegarde les claviers et de copier/coller la version texte de la regexp proposée par le site
http://regex101.com/
D'accord c'est de langliche mais c'est précis, concis et surtout fidèle à la sémantique de la regex.
Re: Regex pour inserer du texte dans un fichier
Posté : dim. 25 juin 2017 17:35
par Tlem
@Mickell
Heuuu, concernant les commentaires, je parle évidemment de ceux que je mettrais dans
le code final. ^^
@jchd
J'avais bien utilisé ce site pour mes recherches, mais il faut un minimum de maitrise/compréhension des expressions régulières (ce qui je l'avoue honteusement n'est pas mon cas

)
Re: Regex pour inserer du texte dans un fichier
Posté : lun. 26 juin 2017 10:41
par jchd
@tlem,
Je parlais juste des commentaires. A titre d'exemple, la regexp de Mikell produit cette explication :
/
(?ms)(.*^\h*command\.(?:\w+\.)*(\d+)\.\N+\R?)\K
/
g
(?ms)
match the remainder of the pattern with the following effective flags: gms
m modifier: multi line. Causes ^ and $ to match the begin/end of each line (not only begin/end of string)
s modifier: single line. Dot matches newline characters
1st Capturing Group (.*^\h*command\.(?:\w+\.)*(\d+)\.\N+\R?)
.*
matches any character
* Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
^ asserts position at start of a line
\h*
matches any horizontal whitespace character (equal to [[:blank:]])
* Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
command matches the characters command literally (case sensitive)
\. matches the character . literally (case sensitive)
Non-capturing group (?:\w+\.)*
* Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
\w+
matches any word character (equal to [a-zA-Z0-9_])
\. matches the character . literally (case sensitive)
2nd Capturing Group (\d+)
\. matches the character . literally (case sensitive)
\N+
matches any non-newline character
\R?
matches any Unicode newline sequence; can be modified using verbs
\K resets the starting point of the reported match. Any previously consumed characters are no longer included in the final match
Global pattern flags
g modifier: global. All matches (don't return after first match)
Il est juste dommage que l'indentation soit perdue au passage.
Re: Regex pour inserer du texte dans un fichier
Posté : lun. 26 juin 2017 21:34
par mikell
C'est beaucoup plus une analyse détaillée qu'un commentaire pratique. Par exemple ça ne précise pas que l'expression matche une position plutôt qu'une quelconque suite de caractères, ce qui n'est pas forcément évident dans un SRER
Re: Regex pour inserer du texte dans un fichier
Posté : dim. 02 juil. 2017 02:24
par Tlem
Par manque de temps, j'avance doucement, mais bon, ça prend forme.
Cette fois-ci, je souhaite supprimer toute la nouvelle section.
En cherchant sur Regex101 je suis arrivé à ça :
Code : Tout sélectionner
$sAu3PropContent = StringRegExpReplace($sAu3PropContent, '#\h+(\d+)\h+Titre de la Section.*\r\n', "") ; Delete section title
$sAu3PropContent = StringRegExpReplace($sAu3PropContent, '.*command.*\.' & $sNumber & '\..*\r\n', "") ; Delete command line with $sNumber
Return StringRegExpReplace($sAu3PropContent, '(\R[\h\v]+\R)', @CRLF & @CRLF) ; Replace multiple blank line by one blanc line
Bien que cela fonctionne, je me doute que c'est pas très optimisé.
Si il y a des suggestions ...

Re: Regex pour inserer du texte dans un fichier
Posté : dim. 02 juil. 2017 11:59
par mikell
A priori, si la nouvelle section a été insérée comme décrit dans les posts précédents ET si elle ne contient pas de dièse, ça devrait suffire :
(supprime jusqu'au prochain # rencontré)
Re: Regex pour inserer du texte dans un fichier
Posté : dim. 02 juil. 2017 12:54
par Tlem
Effectivement c'est mieux.
Il faut juste s'assurer qu'il n'y a pas de # dans la section ...
Maintenant, si un user modifie la section manuellement ce sera moins bien, mais bon personne n'est sensé faire ça !!!
Du coup je prends ta solution et comme je connais la section, je vais même faire :
Code : Tout sélectionner
$a = StringRegExpReplace($a, '#\h+' & $sNumber & '[^#]+', @CRLF)
Merci Michel.

Re: Regex pour inserer du texte dans un fichier
Posté : dim. 02 juil. 2017 14:34
par orax
Il y a un x pour les lignes qui concernent la béta. Il peut aussi y avoir un #, comme dans
# 32 Open #include File
.
https://regex101.com/r/0BjXh8/1/
Code : Tout sélectionner
$a = StringRegExpReplace($a, '(?m)^\h*#x?\h+' & $sNumber & '\N+[^#]+', @CRLF)
Re: Regex pour inserer du texte dans un fichier
Posté : dim. 02 juil. 2017 14:47
par mikell
Tlem a écrit : ↑dim. 02 juil. 2017 12:54Il faut juste s'assurer qu'il n'y a pas de # dans la section ...
Ouais t'as raison. Modification : supprime tout jusqu'au prochain # qui se trouve en début de ligne
Re: Regex pour inserer du texte dans un fichier
Posté : dim. 02 juil. 2017 18:57
par Tlem
Merci bien pour cette amélioration. Maintenant, pour répondre à Orax, cette section, c'est moi qui la construit, donc je sais comment elle est faites.
De plus la ligne du début est balisée tel que "# xx Titre de ma section", dont je connait xx et le titre. Comme je sais qu'il ne faut pas utiliser le signe # ailleurs, aucun risque de "plantage".
Maintenant la dernière Regex de Michel me plait plus puisque qu'elle supprime du début connu jusqu'au # en début de ligne suivant (et donc d'une éventuelle nouvelle section).
En ce qui me concerne, les réponses apportées correspondent à la demande. ^^