Regex for comments-block
Règles du forum
- Merci de consulter la section "Règles du forum" et plus particulièrement "Règles et Mentions Légales du site autoitscript.fr" avant d'écrire un message.
Regex for comments-block
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!
(?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!
- orax
- Modérateur
- Messages : 1479
- Enregistré le : lun. 23 mars 2009 04:50
- Localisation : ::1
- Status : Hors ligne
Re: Regex for comments-block
https://regex101.com/r/dJ7xH7
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.
Code : Tout sélectionner
(?msx)
^\h*\#(?:cs|comments-start)\h*.+?\R+
(?:
[^\#] | \#(?!cs|ce|comments-start|comments-end)
|
(?R)
)*
^\h*\#(?:ce|comments-end)
De petits détails peuvent faire toute la différence. — Quand la boule de neige commence à rouler… poussez-la. (Columbo)
Re: Regex for comments-block
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
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
- jchd
- 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
Tout à fait :
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 !
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)
)
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
Re: Regex for comments-block
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?
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
; 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
Re: Regex for comments-block
Remplace \1 par \5 dans le remplacement
Edit : super cette regex JC. Ca donne un bon exemple d'utilisation de la récursivité
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 !
- jchd
- 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
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 = " " & "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é.
Re: Regex for comments-block
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
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
Re: Regex for comments-block
@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 !
- jchd
- 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
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.
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é.
- orax
- Modérateur
- Messages : 1479
- Enregistré le : lun. 23 mars 2009 04:50
- Localisation : ::1
- Status : Hors ligne
Re: Regex for comments-block
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
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
D'après moi, le code...
Si $0 ou \0 est utilisé (au lieu de $5 ou \5), il n'y a pas besoin de capturer
Au lieu de mettre...
... le code suivant suffirait, non ?
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]
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 .D'après moi, le code...
pourrait être simplifié par :
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)' & _
')'
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 (?: ... )
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)
Re: Regex for comments-block
Oui, tu as bien compris ma question, et parfaitement répondu à ma question (avec un exemple en plus). Merci
Le script, ça fait gagner beaucoup de temps... à condition d'en avoir beaucoup devant soi !
Re: Regex for comments-block
@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?
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?
- jchd
- 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
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é.
Re: Regex for comments-block
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.
?!
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.
- orax
- Modérateur
- Messages : 1479
- Enregistré le : lun. 23 mars 2009 04:50
- Localisation : ::1
- Status : Hors ligne
Re: Regex for comments-block
Les deux solutions ci-dessous devraient convenir.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.
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)
- mikell
- Spammer !
- Messages : 6292
- Enregistré le : dim. 29 mai 2011 17:32
- Localisation : Deep Cévennes
- Status : Hors ligne
Re: Regex for comments-block
jguinch
$0 est un truc batard apparemment propre à Autoit qui permet de retourner une backreference correspondant au pattern sans groupe capturant
étonnant non ?
$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
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )