Regex pour inserer du texte dans un fichier

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Regex pour inserer du texte dans un fichier

#1

Message 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.
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Avatar du membre
orax
Modérateur
Modérateur
Messages : 1479
Enregistré le : lun. 23 mars 2009 04:50
Localisation : ::1
Status : Hors ligne

Re: Regex pour inserer du texte dans un fichier  

#2

Message 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+)(.*)"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.
De petits détails peuvent faire toute la différence. — Quand la boule de neige commence à rouler… poussez-la. (Columbo)
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: Regex pour inserer du texte dans un fichier

#3

Message 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.
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: Regex pour inserer du texte dans un fichier

#4

Message 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

$s = "ma nouvelle commande"
$a = StringRegExpReplace(FileRead("au3.properties"), _
   "(?ms)(.*^\h*command\.(?:\w+\.)*(\d+)\.\N+\R?)\K", $s & @crlf)
FileWrite("new.txt", $a)
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: Regex pour inserer du texte dans un fichier

#5

Message 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.
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: Regex pour inserer du texte dans un fichier

#6

Message 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 ^^

$txt = FileRead("au3.properties")
$a = Execute("'" & StringRegExpReplace(StringReplace($txt, "'", "''"), _
   "(?ms)(.*^\h*command\.(?:\w+\.)*(\d+)\.\N+\R?)\K", _
   "' & _manouvellesection('$2'+1) & '") & "'")
FileWrite("new.txt", $a)

Func _manouvellesection($var)
  Local $s = "# " & $var & " ma nouvelle section" & @crlf & _
   "command.tralala." & $var & "=tsointsoin" & @crlf & _
   "etc" & @crlf
  Return $s
EndFunc
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: Regex pour inserer du texte dans un fichier

#7

Message 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. ;)
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: Regex pour inserer du texte dans un fichier

#8

Message 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 :mrgreen:
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 :P
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2272
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: Regex pour inserer du texte dans un fichier

#9

Message 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.
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: Regex pour inserer du texte dans un fichier

#10

Message 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 :oops: )
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Avatar du membre
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2272
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: Regex pour inserer du texte dans un fichier

#11

Message 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.
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: Regex pour inserer du texte dans un fichier

#12

Message 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
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: Regex pour inserer du texte dans un fichier

#13

Message 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 ... :roll:
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: Regex pour inserer du texte dans un fichier

#14

Message 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é)

$a = StringRegExpReplace($a, '#\h+(\d+)\h+ma nouvelle section[^#]+', @crlf)
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: Regex pour inserer du texte dans un fichier

#15

Message 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. :bisou:
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Avatar du membre
orax
Modérateur
Modérateur
Messages : 1479
Enregistré le : lun. 23 mars 2009 04:50
Localisation : ::1
Status : Hors ligne

Re: Regex pour inserer du texte dans un fichier

#16

Message 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)
De petits détails peuvent faire toute la différence. — Quand la boule de neige commence à rouler… poussez-la. (Columbo)
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: Regex pour inserer du texte dans un fichier

#17

Message 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 Image

$a = StringRegExpReplace($a, '(?s)#\h+(\d+)\h+ma nouvelle section.+?\R(?=\h*#)', @crlf)
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11773
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: Regex pour inserer du texte dans un fichier

#18

Message 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. ^^
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Répondre