cerhu > comp.lang.* > comp.lang.javascript

Cenekemoi (19/07/2007, 17h24)
Bonjour,

n'étant pas au top sur les expressions régulières, j'en recherche une
qui me permettrait de vider des parties de texte compris entre deux
mot-clés.

Exemple classique avec les mot-clés '<' et '>' afin de retirer les
balises Html : new RegExp("<[^>]*>", "g");

J'aimerais que les deux caractères < et > ci-dessus soient libres, par
exemple: _DEB_ et _FIN_ mais j'ai du mal à ce que tout fonctionne bien.

Mon essai (en m'inspirant de l'exemple ci-dessus):

<script>
var _H1_ = "_DEB_",_H2_ = "_FIN_";

exp = _H1_ +'link rel="stylesheet" href="../styles/drill_print.css"
type="text/css" media="print"'+ _H2_;
exp+= _H1_ +'style'+ _H2_ +'body,td { font-family: Arial; font-size:
9px;}';
exp+= _H1_ +'/style'+ _H2_;
exp+= _H1_ +'/head'+ _H2_;
exp+= _H1_ +'body onload="onLoad();onLoadTest()"'+ _H2_ +'thierry';
exp+= _H1_ +'/body'+ _H2_;

var reg = new RegExp(_H1_ +"[^"+ _H2_ +"]*"+ _H2_, "g");
alert( exp.replace(reg,"") );
</script>

Résultat:
_DEB_link rel="stylesheet" href="../styles/drill_print.css"
type="text/css" media="print"_FIN_body,td { font-family: Arial;
font-size: 9px;}thierry

C'est lié a priori au caractère "_" dans "drill_print", mais ça ne
m'avance guère.

Des idées ?...

Merci d'avance...
Olivier Miakinen (19/07/2007, 23h26)
Le 19/07/2007 17:24, Cenekemoi a écrit :
> n'étant pas au top sur les expressions régulières, j'en recherche une
> qui me permettrait de vider des parties de texte compris entre deux
> mot-clés.
> Exemple classique avec les mot-clés '<' et '>' afin de retirer les
> balises Html : new RegExp("<[^>]*>", "g");


1) Syntaxe JavaScript
---------------------

Tu peux simplifier l'écriture en écrivant :
/<[^>]*>/g
au lieu de :
new RegExp("<[^>]*>", "g")

Bien entendu ça ne marchera que si l'expression ne contient pas de
« / », mais elle peut à priori contenir des « " ».

2) Expressions régulières PCRE
------------------------------

Tu peux simplifier l'expression en écrivant :
new RegExp("<.*>", "gU")
ou bien sûr :
/<.*>/gU

(U = Ungreedy = non gourmand, ce qui signifie que l'expression prend le
plus petit motif qui marche au lieu d'aller chercher le plus grand).

> J'aimerais que les deux caractères < et > ci-dessus soient libres, par
> exemple: _DEB_ et _FIN_ mais j'ai du mal à ce que tout fonctionne bien.


Pour des *caractères* différents de < et > cela devrait marcher pareil,
mais pas pour des *chaînes de caractères*.

En effet, avec "_DEB_[^_FIN_]*_FIN_" et la chaîne "_DEB_ MACHIN _FIN_",
le I et le N de MACHIN arrêteront la recherche avant d'aller jusqu'à ton
_FIN_.

En revanche, RegExp("_DEB_.*_FIN", "gU") devrait fonctionner.

> [...]
> C'est lié a priori au caractère "_" dans "drill_print", mais ça ne
> m'avance guère.
> Des idées ?...


Tu dois comprendre que [_FIN_] et [^_FIN_] matchent un seul caractère et
pas un mot. D'ailleurs [^_FIN_] est équivalent à [^____FFNI___IN].
Olivier Miakinen (19/07/2007, 23h31)
Le 19/07/2007 23:26, jé répondais à Cenekemoi :
> new RegExp("_DEB_.*_FIN", "gU");


Si le contenu à virer entre _DEB_ et _FIN_ peut s'étendre sur plus d'une
ligne, il faut rajouter l'option s (DOTALL) ou ça ne marchera pas :

new RegExp("_DEB_.*_FIN", "gUs");
Olivier Miakinen (20/07/2007, 11h02)
Le 19/07/2007 23:31, j'écrivais (à un « _ » près) :
>> new RegExp("_DEB_.*_FIN_", "gU");

> Si le contenu à virer entre _DEB_ et _FIN_ peut s'étendre sur plus d'une
> ligne, il faut rajouter l'option s (DOTALL) ou ça ne marchera pas :
> new RegExp("_DEB_.*_FIN_", "gUs");


En reprenant ton code, cela donnera donc :

<script>
var _H1_ = "_DEB_",_H2_ = "_FIN_";

exp = [...]

var reg = new RegExp(_H1_ + ".*" + _H2_, "gUs");
alert(exp.replace(reg, ""));
</script>
Cenekemoi (23/07/2007, 10h00)
Bonjour à Olivier Miakinen <om+news> qui nous a écrit :
> Le 19/07/2007 17:24, Cenekemoi a écrit :
> 1) Syntaxe JavaScript
> ---------------------
> Tu peux simplifier l'écriture en écrivant :
> /<[^>]*>/g
> au lieu de :
> new RegExp("<[^>]*>", "g")


Oui, merci, je le sais ; je le mettais sous cette forme pour être plus
proche du code que je proposais (avec le "<" variable)...

> Bien entendu ça ne marchera que si l'expression ne contient pas de
> « / », mais elle peut à priori contenir des « " ».
> 2) Expressions régulières PCRE
> ------------------------------
> Tu peux simplifier l'expression en écrivant :
> new RegExp("<.*>", "gU")


Désolé, Olivier, mais je te rappelle que PCRE = Perl Compatible Regular
Expressions.

Si tu utilises le genre d'expression ci-dessus en *javascript*, sous FF
tu obtiens le message :
"invalid regular expression flag U"

....et une erreur de syntaxe sous IE.

Normal, Javascript n'est pas compatible PERL...
Olivier Miakinen (23/07/2007, 11h17)
Le 23/07/2007 10:00, Cenekemoi a écrit :
> Désolé, Olivier, mais je te rappelle que PCRE = Perl Compatible Regular
> Expressions.
> Si tu utilises le genre d'expression ci-dessus en *javascript*, sous FF
> tu obtiens le message :
> "invalid regular expression flag U"
> ...et une erreur de syntaxe sous IE.
> Normal, Javascript n'est pas compatible PERL...


Ben mince alors ! On m'aurait menti ?

Citation du « Standard ECMA-262, 3rd Edition - December 1999 » intitulé
« ECMAScript Language Specification », chapitre 15.10 :
-----------------------------------------------------------------------
The form and functionality of regular expressions is modelled after the
regular expression facility in the Perl 5 programming language.
-----------------------------------------------------------------------

Note que tout n'est pas perdu. Même si le flag U n'est pas reconnu, la
syntaxe « *? » doit fonctionner pour faire la même chose :

new RegExp("_DEB_.*?_FIN_", "gs");
Olivier Miakinen (23/07/2007, 11h24)
Le 23/07/2007 11:17, je répondais à Cenekemoi :
> Ben mince alors ! On m'aurait menti ?
> Citation du « Standard ECMA-262, 3rd Edition - December 1999 » intitulé
> « ECMAScript Language Specification », chapitre 15.10 :
> -----------------------------------------------------------------------
> The form and functionality of regular expressions is modelled after the
> regular expression facility in the Perl 5 programming language.
> -----------------------------------------------------------------------


Bon, je viens de comprendre en regardant la doc de PCRE. Ce n'est pas
JavaScript qui n'est pas compatible Perl, mais c'est PCRE qui ne l'est
pas complètement, ayant ajouté des options.

<cit. http://www.pcre.org/pcre.txt>
PCRE_UNGREEDY
This option inverts the "greediness" of the quantifiers so that they
are not greedy by default, but become greedy if followed by "?". It is
not compatible with Perl. It can also be set by a (?U) option setting
within the pattern.
</>

PHP est compatible PCRE, mais JavaScript n'est que compatible Perl.

> Note que tout n'est pas perdu. Même si le flag U n'est pas reconnu, la
> syntaxe « *? » doit fonctionner pour faire la même chose :
> new RegExp("_DEB_.*?_FIN_", "gs");


Ça c'est à la fois Perl et PCRE, donc ça doit marcher.
Cenekemoi (23/07/2007, 11h54)
Bonjour à Olivier Miakinen <om+news> qui nous a écrit :
> PHP est compatible PCRE, mais JavaScript n'est que compatible Perl.
>> Note que tout n'est pas perdu. Même si le flag U n'est pas reconnu,
>> la syntaxe « *? » doit fonctionner pour faire la même chose :
>> new RegExp("_DEB_.*?_FIN_", "gs");

> Ça c'est à la fois Perl et PCRE, donc ça doit marcher.


Si on enlève le "s", tout baigne ! Merci beaucoup...
Accessoirement, à quoi est sensé servir le "s" ci-dessus en Perl ?

Maintenant, STP, pourrais-tu décrire le rôle dévolu à chacun des trois
caractères ".*?", je te remercie d'avance

J'ai par ailleurs fini par trouver sur le web ta syntaxe mais encadrée
par des parenthèses "(.*?)", quelle différence cela fait-il avec ta
proposition ?
Olivier Miakinen (23/07/2007, 12h23)
Le 23/07/2007 11:54, Cenekemoi a écrit :
> Bonjour à Olivier Miakinen <om+news> qui nous a écrit :
>> PHP est compatible PCRE, mais JavaScript n'est que compatible Perl.
>>> Note que tout n'est pas perdu. Même si le flag U n'est pas reconnu,
>>> la syntaxe « *? » doit fonctionner pour faire la même chose :
>>> new RegExp("_DEB_.*?_FIN_", "gs");

>> Ça c'est à la fois Perl et PCRE, donc ça doit marcher.

> Si on enlève le "s", tout baigne ! Merci beaucoup...


Pourtant, d'après la doc de PCRE c'est bien une option de Perl.

> Accessoirement, à quoi est sensé servir le "s" ci-dessus en Perl ?


<cit. http://www.pcre.org/pcre.txt>
PCRE_DOTALL
If this bit is set, a dot metacharater in the pattern matches all char-
acters, including those that indicate newline. Without it, a dot does
not match when the current position is at a newline. This option is
equivalent to Perl's /s option, and it can be changed within a pattern
by a (?s) option setting. A negative class such as [^a] always matches
newline characters, independent of the setting of this option.
</cit.>

Explication en français : par défaut, le métacaractère « point » peut
représenter n'importe quel caractère *sauf* un saut de ligne. Donc la
séquence « .* » ne peut pas aller au delà d'une seule ligne de texte.

Du coup, /_DEB_.*_FIN_/ fonctionnera sur ce premier exemple :

Essai_DEB_sur une seule ligne_FIN_.

.... mais pas sur le suivant :

Essai_DEB_sur
plusieurs
lignes_FIN_.

L'option /s (ou PCRE_DOTALL) permet de franchir les sauts de ligne.

> Maintenant, STP, pourrais-tu décrire le rôle dévolu à chacun des trois
> caractères ".*?", je te remercie d'avance


.. = n'importe quel caractère sauf les sauts de ligne (à moins de /s)
* = répéter ce qui précède n'importe quel nombre de fois (y compris
éventuellement 0 fois), et privilégier le résultat le plus long
si plusieurs sont possibles.
*? = idem * mais privilégier le résultat le plus court si plusieurs
sont possibles.

Par exemple, avec la chaîne "_DEB_xx_FIN_ uu _DEB_yy_FIN_" :
/_DEB_.*_FIN_/ --> le « .* » trouvera "xx_FIN_ uu _DEB_yy"
/_DEB_.*?_FIN_/ --> le « .*? » trouvera "xx", puis "yy".

> J'ai par ailleurs fini par trouver sur le web ta syntaxe mais encadrée
> par des parenthèses "(.*?)", quelle différence cela fait-il avec ta
> proposition ?


Aucune, puisque tu ne te sers pas de ces « parenthèses capturantes »
(qui retournent les valeurs trouvées dans \1, \2, \3, etc.). Elles
sont inutiles ici.
Cenekemoi (23/07/2007, 15h09)
Bonjour à Olivier Miakinen <om+news> qui nous a écrit :
> (...)
> L'option /s (ou PCRE_DOTALL) permet de franchir les sauts de ligne.


Comme je travaille avec des chaînes sans saut de ligne, je comprend que
cela marche sans le "s"

> . = n'importe quel caractère sauf les sauts de ligne (à moins de /s)
> * = répéter ce qui précède n'importe quel nombre de fois (y compris
> éventuellement 0 fois), et privilégier le résultat le plus long
> si plusieurs sont possibles.
> *? = idem * mais privilégier le résultat le plus court si plusieurs
> sont possibles.
> Par exemple, avec la chaîne "_DEB_xx_FIN_ uu _DEB_yy_FIN_" :
> /_DEB_.*_FIN_/ --> le « .* » trouvera "xx_FIN_ uu _DEB_yy"
> /_DEB_.*?_FIN_/ --> le « .*? » trouvera "xx", puis "yy".


Merci beaucoup ! Comme d'habitude avec toi, les explications sont
limpides et argumentées...du coup, je comprend beaucoup mieux certains
rôles particuliers de RegExp que j'ai eu l'occasion de voir
Cenekemoi (23/07/2007, 15h36)
Bonjour à Cenekemoi <thierry> qui nous a écrit :
> Merci beaucoup ! Comme d'habitude avec toi, les explications sont
> limpides et argumentées...du coup, je comprend beaucoup mieux certains
> rôles particuliers de RegExp que j'ai eu l'occasion de voir


Olivier,
pendant que j'y suis, l'expression "<[^>]*>" (pour enlever les balises
html) aurait pu être simplifiée en "<.*?>", n'est-il pas ? Ou bien
représente-t-elle autre chose qui m'échappe ?
Olivier Miakinen (23/07/2007, 15h42)
Le 23/07/2007 15:09, Cenekemoi a écrit :
> Bonjour à Olivier Miakinen <om+news> qui nous a écrit :
>> (...)
>> L'option /s (ou PCRE_DOTALL) permet de franchir les sauts de ligne.

> Comme je travaille avec des chaînes sans saut de ligne, je comprend que
> cela marche sans le "s"


Si jamais tu en avais besoin un jour, il faudrait utiliser l'autre
moyen de spécifier « DOTALL », qui est (si j'ai bien compris car je
n'ai jamais utilisé cette syntaxe) :
"(?s)_DEB_.*?_FIN_"

Ou bien, plus simple (enfin... du moins je suis à peu près sûr que ça
doit marcher) :
"_DEB_(.|\n)*?_FIN_"

Et encore plus simple, s'il y a un caractère dont tu sais qu'il
n'appartiendra jamais à tes chaînes, par exemple "§" :
"_DEB_[^§]*?_FIN_"

> [...] Comme d'habitude avec toi, les explications sont
> limpides et argumentées...du coup, je comprend beaucoup mieux certains
> rôles particuliers de RegExp que j'ai eu l'occasion de voir


Merci. Mais si tu as un peu de temps et que tu baragouines suffisamment
l'anglais, je te conseille la lecture de <http://www.pcre.org/pcre.txt>.

Cela dit, tu peux commencer par une doc plus accessible et en français :
<http://fr.php.net/manual/fr/reference.pcre.pattern.syntax.php>
<http://fr.php.net/manual/fr/reference.pcre.pattern.modifiers.php>
Olivier Miakinen (23/07/2007, 15h43)
Le 23/07/2007 15:36, Cenekemoi a écrit :
> pendant que j'y suis, l'expression "<[^>]*>" (pour enlever les balises
> html) aurait pu être simplifiée en "<.*?>", n'est-il pas ?


[OUI]

Modulo l'histoire des sauts de ligne, car [^>] accepte tout caractère
sauf le >, mais y compris \n.
Cenekemoi (23/07/2007, 15h45)
Bonjour à Olivier Miakinen <om+news> qui nous a écrit :
> Merci. Mais si tu as un peu de temps et que tu baragouines
> suffisamment l'anglais, je te conseille la lecture de
> <http://www.pcre.org/pcre.txt>.
> Cela dit, tu peux commencer par une doc plus accessible et en
> français :
> <http://fr.php.net/manual/fr/reference.pcre.pattern.syntax.php>
> <http://fr.php.net/manual/fr/reference.pcre.pattern.modifiers.php>


Tu l'as dit toi-même, c'est le temps qui manque.
Je pense sincèrement que pour dominer les expressions régulières, il
faut les pratiquer avec des test, des exemples, des retests, etc...
Je le ferais certainement un de ces quatre mais, pour un besoin ponctuel
comme celui que j'ai, le forum m'a paru le plus approprié après quelques
(certainement insuffisantes) recherches via notre pote Google.
Olivier Miakinen (23/07/2007, 15h54)
Le 23/07/2007 15:45, Cenekemoi a écrit :
> Tu l'as dit toi-même, c'est le temps qui manque.


Comme toujours. ;-)

> Je pense sincèrement que pour dominer les expressions régulières, il
> faut les pratiquer avec des test, des exemples, des retests, etc...


Ce n'est pourtant jamais comme ça que j'ai pratiqué, mais je suis
peut-être bien atypique. Je me suis toujours contenté de la doc, et
lorsque j'ai eu besoin d'une expression régulière je ne me rappelle
pas avoir eu besoin de m'y reprendre à deux fois.

> Je le ferais certainement un de ces quatre mais, pour un besoin ponctuel
> comme celui que j'ai, le forum m'a paru le plus approprié après quelques
> (certainement insuffisantes) recherches via notre pote Google.


Oui, bien sûr.

Discussions similaires
Expression régulière

Expression régulière

Expression reguliere

expression régulière


Fuseau horaire GMT +2. Il est actuellement 03h33. | Privacy Policy