Regex for comments-block

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
mdanielm
Membre émérite
Membre émérite
Messages : 254
Enregistré le : mer. 11 déc. 2013 19:48
Status : Hors ligne

Regex for comments-block

#1

Message par mdanielm »

En voilà une qui convenait:

(?ims)(^\h*#(?:cs|comments-start)(?!\w).+?#(?:ce|comments-end)[^\r\n]*)(?:\R|$)

...avant que je me souvienne de la doc:
"Les instructions #comments-start et #comments-end peuvent être imbriquées."

Dans ce cas elle ne convient plus!
Quelqu'un a une idée ?
Exemple:

#commentS-start com1
com2
#cs com3
com4
#ce com5
#coMMents-end com6

Bonne finale!
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 for comments-block

#2

Message par orax »

https://regex101.com/r/dJ7xH7

Code : Tout sélectionner

(?msx)
^\h*\#(?:cs|comments-start)\h*.+?\R+

(?:
  [^\#] | \#(?!cs|ce|comments-start|comments-end)
|
  (?R)
)*

^\h*\#(?:ce|comments-end)
Je n'ai pas encore vérifié si ça fonctionne vraiment correctement. Et on peut sans doute faire mieux, elle n'est peut-être pas très optimisée.
De petits détails peuvent faire toute la différence. — Quand la boule de neige commence à rouler… poussez-la. (Columbo)
mdanielm
Membre émérite
Membre émérite
Messages : 254
Enregistré le : mer. 11 déc. 2013 19:48
Status : Hors ligne

Re: Regex for comments-block

#3

Message par mdanielm »

Bonjour,
Je crois que non, la recherche s'arrête au premier #ce rencontré.
Je l'ai testé en situation: dans mon script.
J'ai rajouté une capture car je veux encadrer le bloc par des balises <span...

(?msx)
^\h* (\#(?:cs|comments-start)\h*.+?\R+

(?:
[^\#] | \#(?!cs|ce|comments-start|comments-end)
|
(?R)
)* )

J'ai déjà une solution à mon problème mais elle tient sur 18 lignes avec 2 while imbriqués.
Je me demandais comment utiliser la récursivité dans une regex.
Merci
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 for comments-block

#4

Message par jchd »

Tout à fait :

Code : Tout sélectionner

(?imsx)
(?(DEFINE) (?<CSline> ^ \h* \# (?: cs | comments-start ) \b \N* \R ) )
(?(DEFINE) (?<CEline> ^ \h* \# (?: ce | comments-end ) \b \N* \R ) )
(?(DEFINE) (?<Comment> ^ \N*? (?! (?&CSline) | (?&CEline) ) \R ) )
(?(DEFINE) (?<Cblock> (?&CSline) (?: (?&Cblock)* | (?&Comment)*? )* (?&CEline) ) )
(
  (?&Cblock)
)
L'emploi de (?(DEFINE) ...) n'est là que pour clarifier la structure de l'expression. On peut évidemment faire tout ça "inline", mais c'est un brin indigeste. Certes ça crée un peu de backtracking mais c'est tellement plus clair !
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
mdanielm
Membre émérite
Membre émérite
Messages : 254
Enregistré le : mer. 11 déc. 2013 19:48
Status : Hors ligne

Re: Regex for comments-block

#5

Message par mdanielm »

Cette fonctionnalité semble très intéressante.
Lorsque j'utilise votre regex comme çi-dessous, les blocs de commentaires disparaissent et sont remplacés par:
<span class="S2"></span>
Sans doute un problème de capture?
func CommentBlock(byref $data) ;style "S2"
   ; JCHD
Local $regex = _
'(?imsx)' & _
'(?(DEFINE) (?<CSline> ^ \h* \# (?: cs | comments-start ) \b \N* \R ) )' & _
'(?(DEFINE) (?<CEline> ^ \h* \# (?: ce | comments-end ) \b \N* \R ) )' & _
'(?(DEFINE) (?<Comment> ^ \N*? (?! (?&CSline) | (?&CEline) ) \R ) )' & _
'(?(DEFINE) (?<Cblock> (?&CSline) (?: (?&Cblock)* | (?&Comment)*? )* (?&CEline) ) )' & _
'(' & _
'  (?&Cblock)' & _
')'

$data = StringRegExpReplace($data, $regex, '<span class="S2">\1</span>')

EndFunc
Avatar du membre
jguinch
Modérateur
Modérateur
Messages : 2511
Enregistré le : lun. 14 févr. 2011 22:12
Status : Hors ligne

Re: Regex for comments-block

#6

Message par jguinch »

Remplace \1 par \5 dans le remplacement

Edit : super cette regex JC. Ca donne un bon exemple d'utilisation de la récursivité
Le script, ça fait gagner beaucoup de temps... à condition d'en avoir beaucoup devant soi !
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 for comments-block

#7

Message par jchd »

Code : Tout sélectionner

Local $s = _
	'; "Comment-line"' & @CRLF & _
	"$x='' ; chaîne ""vide""" & @CRLF & _
	'$x = "a''''a;a""a" ; Comment-line' & @CRLF & _
	"y'a rien à voir ici" & @CRLF & _
	"$x = ""a"" ;$x='b'" & @CRLF & _
	"" & @CRLF & _
	"$x=""a""&';b'" & @CRLF & _
	"#cs xyz" & @CRLF & _
	"  gna" & @CRLF & _
	"#cs xyz" & @CRLF & _
	"  gna gna" & @CRLF & _
	"#ce xyz" & @CRLF & _
	"#ce xyz" & @CRLF & _
	";No match:" & @CRLF & _
	"$x = 'bb;b'" & @CRLF & _
	"#cs xyz" & @CRLF & _
	"  gna gna" & @CRLF & _
	"#ce xyz" & @CRLF & _
	'$x = "&nbsp;" & "bb"           ;;ccc'

CommentBlock($s)
ConsoleWrite($s & @LF)

Func CommentBlock(byref $data) ;style "S2"
    ; JCHD
	Local $regex = _
		'(?imsx)' & _
		'(?(DEFINE) (?<CSline> ^ \h* \# (?: cs | comments-start ) \b \N* \R ) )' & _
		'(?(DEFINE) (?<CEline> ^ \h* \# (?: ce | comments-end ) \b \N* \R ) )' & _
		'(?(DEFINE) (?<Comment> ^ \N*? (?! (?&CSline) | (?&CEline) ) \R ) )' & _
		'(?(DEFINE) (?<Cblock> (?&CSline) (?: (?&Cblock)* | (?&Comment)*? )* (?&CEline) ) )' & _
		'(' & _
		'   (?&Cblock)' & _
		')'
    $data = StringRegExpReplace($data, $regex, '<span class="S2">$0</span>')
EndFunc
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
mdanielm
Membre émérite
Membre émérite
Messages : 254
Enregistré le : mer. 11 déc. 2013 19:48
Status : Hors ligne

Re: Regex for comments-block

#8

Message par mdanielm »

Génial!
C'était donc \0 ou \5 mais pas \1 !
Je vais essayer de placer ma balise ouvrante immédiatement avant #cs et pas en début de ligne et la fermante en fin de ligne #ce et pas au début de la ligne suivante, ça me semble plus logique.
Bonsoir
Avatar du membre
jguinch
Modérateur
Modérateur
Messages : 2511
Enregistré le : lun. 14 févr. 2011 22:12
Status : Hors ligne

Re: Regex for comments-block

#9

Message par jguinch »

@JC : si tu peux m'éclairer un peu : j'ai jamais vraiment compris à quoi sert le fameux $0...
Le script, ça fait gagner beaucoup de temps... à condition d'en avoir beaucoup devant soi !
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 for comments-block

#10

Message par jchd »

Daniel,
Ca peut s'avérer un poil plus sportif ! Je pense que ça sera plus facile avec un enrobage Execute et une imbricatrion de String*** dans la partie Replace. Sinon je ne vois pas trop comment faire ça proprement pour que ça fonctionne dans tous les cas. Je n'ai pas non plus trop le temps de creuser plus avant.

jguinch,
Faudrait demander à Jon, ou déterminer ça comme je fais, par tâtonnement et déduction... La version *Replace est une création qui n'a pas d'équivalent dans la bibliothèque PCRE, donc d'implémentation libre.
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
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 for comments-block

#11

Message par orax »

L'expression régulière de jchd fonctionne très bien, mais j'ai quand même voulu essayé de corriger la mienne pour mieux comprendre mes erreurs. Donc voilà la v2 (qui semble mieux fonctionner) : https://regex101.com/r/dJ7xH7/2

Code : Tout sélectionner

(?imx)
^\h*\# (?>cs|comments-start) (?:\h\N*|$) \R

(?:
  (?!\h*\# (?>cs|comments-start|ce|comments-end) (?:\h|$) ) \N*\R
|
  (?R)
)*

\h*\# (?>ce|comments-end) (?:\h\N*|$) \R?

En exportant un fichier HTML depuis SciTE, j'ai remarqué que le code est très lourd. Par exemple, pour chaque ligne commentée il ajoute un <span class="S2">. Je ne pense pas que ce soit nécessaire. On pourrait aussi utiliser <pre> plutôt que de mettre plein de &nbsp;.
D'après moi, le code...
<span class="S2">&nbsp;&nbsp;gna</span><br />
<span class="S2">#cs xyz</span><br />
<span class="S2">&nbsp;&nbsp;gna gna</span><br />
<span class="S2">#ce xyz</span><br />
<span class="S2">#ce xyz</span><br />
pourrait être simplifié par :
<pre><code><span class="S2">  gna<br>
#cs xyz<br>
  gna gna<br>
#ce xyz<br>
#ce xyz<br></span></pre></code>

Si $0 ou \0 est utilisé (au lieu de $5 ou \5), il n'y a pas besoin de capturer (?&Cblock) dans un groupe numéroté, me semble-t-il.
Au lieu de mettre...

Code : Tout sélectionner

'(' & _
'   (?&Cblock)' & _
')'
... le code suivant suffirait, non ?

Code : Tout sélectionner

(?&Cblock)' & _

jguinch,
Je ne sais pas si j'ai bien compris ta question, mais, pour moi, $0 ou \0 représente tout ce qui a été trouvé depuis le début ou depuis le dernier \K, même si la chaîne est dans un groupe non capturant comme (?: ... ).
[codeautoit]ConsoleWrite(StringRegExpReplace("abcdef", "cd", "*\0*") & @CRLF) ; ab*cd*ef
ConsoleWrite(StringRegExpReplace("abcdef", "(?:cd)", "*\0*") & @CRLF) ; ab*cd*ef
ConsoleWrite(StringRegExpReplace("abcdef", "c\Kd", "*\0*") & @CRLF) ; abc*d*ef[/codeautoit]
Modifié en dernier par orax le lun. 11 juil. 2016 21:11, modifié 1 fois.
Raison : Ajout d'un exemple avec (?: ... )
De petits détails peuvent faire toute la différence. — Quand la boule de neige commence à rouler… poussez-la. (Columbo)
Avatar du membre
jguinch
Modérateur
Modérateur
Messages : 2511
Enregistré le : lun. 14 févr. 2011 22:12
Status : Hors ligne

Re: Regex for comments-block

#12

Message par jguinch »

Oui, tu as bien compris ma question, et parfaitement répondu à ma question (avec un exemple en plus). Merci :wink:
Le script, ça fait gagner beaucoup de temps... à condition d'en avoir beaucoup devant soi !
mdanielm
Membre émérite
Membre émérite
Messages : 254
Enregistré le : mer. 11 déc. 2013 19:48
Status : Hors ligne

Re: Regex for comments-block

#13

Message par mdanielm »

@Orax,
Ta version 2 convient mais je ne comprends pas la logique pour le moment
Avec la regex de jchd, je comprends la logique globale, bien que:
(?<Comment> ^ \N*? (?! (?&CSline) | (?&CEline) ) \R ) )
supporterait une explication pour moi.
look-ahead négatif : contre-sens, peut-être look-ahead par négation?

Une traduction en français aiderait:
"n'importe quoi sauf @crlf répété 0 ou plus mais aussi peu que possible, et NON suivi de CSline, ni de CEline, et terminé par \r\n"

C'est de cette façon qu'il faut traduire?
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 for comments-block

#14

Message par jchd »

Oui, je pense que c'est une définition correcte de toute ligne qui est à l'intérieur d'un block #cs ... #ce et qui n'est ni un #ce ni un nouveau #cs puisqu'ils peuvent être imbriqués.
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
mdanielm
Membre émérite
Membre émérite
Messages : 254
Enregistré le : mer. 11 déc. 2013 19:48
Status : Hors ligne

Re: Regex for comments-block

#15

Message par mdanielm »

Je viens de comprendre la signification de
?!
look ahead négationnel (..si l'adjectif existe!)
Regarder devant, comme je lis de gauche à droite, je pensais 'regarder après' alors qu'en fait c'est regarder précédemment.
Du coup je comprends ta définition de 'comment'.
La doc AutoIt manque cruellement d'exemples.
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 for comments-block

#16

Message par orax »

mdanielm a écrit :Je vais essayer de placer ma balise ouvrante immédiatement avant #cs et pas en début de ligne et la fermante en fin de ligne #ce et pas au début de la ligne suivante, ça me semble plus logique.
Les deux solutions ci-dessous devraient convenir.
J'ai essayé de le faire avec la regex de JCHD et la mienne.
► Afficher le textevoir les regex
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 for comments-block

#17

Message par mikell »

jguinch
$0 est un truc batard apparemment propre à Autoit qui permet de retourner une backreference correspondant au pattern sans groupe capturant

Code : Tout sélectionner

    ConsoleWrite(StringRegExpReplace("abcdef", "cd", "*\0*") & @CRLF)     ; ab*cd*ef
    ConsoleWrite(StringRegExpReplace("abcdef", "(cd)", "*\0*") & @CRLF)     ; ab*cd*ef
    ConsoleWrite(StringRegExpReplace("abcdef", "(cd)", "*\1*") & @CRLF)     ; ab*cd*ef
    ConsoleWrite(StringRegExpReplace("abcdef", "b(cd)", "*\0*") & @CRLF)     ; a*bcd*ef
    ConsoleWrite(StringRegExpReplace("abcdef", "b(cd)", "*\1*") & @CRLF)     ; a*cd*ef
étonnant non ? :mrgreen:
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Répondre