Le 05/06/2008 14:18, SAM a écrit :
sauf erreur de copier-coller,
SAM disait qu'un RegExp construit à partir d'une chaîne contenant '+\+'
ne plante pas sur Safari (et retourne même une valeur non nulle).
Je viens de re-vérifier :
javascript:alert(navigator.userAgent.match(RegExp(' AppleWebKit\/[^ ]+\+
')));
dans mon Safari qui en est très content et me renvoie son Nom et N°
au lieu de faire "error" comme dans Fx
Ah ! D'après Bertrand (Labévue), c'est que ta version de Safari est plus
ancienne que la sienne.
tests Safari 2 :
Je les mets dans un autre ordre afin de les commenter.
3) javascript:alert("abbc abbb+c".match(RegExp('ab+\\+c')));
abbb+c
Pas de surprise ici. La RegExp vaut /ab+\+c/, qui demande une lettre a
suivie d'un nombre quelconque (non nul) de lettres b, puis d'un +, avant
de finir par une lettre c.
5) javascript:alert("abbc abbb+c".match(RegExp('a(b+)+c')));
abbc,bb
Cette RegExp est un peu stupide et inefficace, mais elle est correcte.
Entre le a et le c, je voudrais un nombre non nul de fois une séquence
d'un nombre non nul de b.
Elle est stupide car (b+)+ est équivalent à (b+), et inefficace car
l'interprète de RegExp risque de devoir étudier un grand nombre de cas
possibles avant de décider qu'il n'y a pas de réponse. Par exemple, dans
le cas "abbbbX", il étudiera :
a(bbbb) -> erreur
a(bbb)(b) -> erreur
a(bb)(bb) -> erreur
a(b)(bbb) -> erreur
a(bb)(b)(b) -> erreur
a(b)(bb)(b) -> erreur
a(b)(b)(bb) -> erreur
a(b)(b)(b)(b) -> erreur
et le nombre de cas augmente exponentiellement avec la longueur !
Noter que les parenthèses internes sont capturantes, ce pourquoi on a
comme résultat « abbc,bb » et non simplement « abbc ».
4) javascript:alert("abbc abbb+c".match(RegExp('a(?:b+)+c')));
abbc
Ici, j'ai juste fait en sorte que les parenthèses ne soient pas
capturantes. Le « (?:b+)+ » est donc équivalent à ce que serait
« b++ » si cette syntaxe (stupide) était autorisée.
1) javascript:alert("abbc abbb+c".match(RegExp('ab++c')));
2) javascript:alert("abbc abbb+c".match(RegExp('ab+\+c')));
abbc
Ces deux syntaxes, comme on a vu, créent une RegExp égale à /ab++c/
puisque le '\+' est transformé en '+' lors de la lecture de la chaîne
de caractères.
Visiblement, la version récente de Safari reconnaît qu'il est idiot
d'enchaîner deux quantificateurs '+' de suite, tandis que la version
plus ancienne ne se pose pas de questions.
Noter qu'on peut parfois rencontrer deux quantificateurs de suite,
mais avec une sémantique modifiée. Ainsi, '*?' signifie '*' en inversant
la gourmandise de la recherche, et '+?' signifie '+' avec le même
changement de gourmandise. Mais '++' n'est pas prévu.
----------------------------------------------------------------------
Et donc, pour en revenir à l'expression initiale, Safari 2
interprète ceci :
RegExp(' AppleWebKit\/[^ ]+\+ ')
qui est équivalent à ceci :
RegExp(' AppleWebKit\/[^ ]++ ')
comme s'il lisait cela :
RegExp(' AppleWebKit\/[^ ]+ ')
(sauf qu'il consomme plus de ressources pour ça).