OVH Cloud OVH Cloud

[REGEXP] sous motif ?

3 réponses
Avatar
Guillaume
Bonjour,

A ce jour j'utilise les expressions régulières type PERL sous PHP
pour analyser du code HTML, et plus précisément, du code javascript.

Exemple de page HTML :
----------------------
<html>
<head><title></title></head>
<body>
[... code html ...]
<script language="javascript">var var1="toto";var var2="titi";var var310.4;var var4 = "";var var5 = "1";</script>
[... code html ...]
</body>
</html>
----------------------

Dans cette page, je souhaiterais :

- Extraire les portions de code javascript qui ne contiennent que des
variables (en fait, la seule balise que j'ai laissé dans l'exemple
ci-dessus)

- Extraire de la chaîne trouvée, les paires clé=valeur trouvées

Tout cela en une seule expression régulière, en se basant sur le fait
que le masque "var cle=valeur;" peut être répété "à l'infini". :)

Quelqu'un connaîtrait-il la syntaxe d'un masque répondant à mes
critères ?

J'ai bien essayé celui-ci '`<script
language="javascript">(?:\s*var\s([^\s=]+)\s*=\s*(?:"|\')?([^\s"\']*)(?:"|\')?\s*;)+</script>`ms'
mais sans succès ! :( Ce masque ne retourne que les résultats pour
la dernière paire clé=valeur trouvée !

Résultat avec preg_match_all :
------------------------------
Array
(
[0] => Array
(
[0] => <script language="javascript">var var1="toto";var
var2="titi";var var3= 10.4;var var4 = "";var var5 = "1";</script>
)

[1] => Array
(
[0] => var5
)

[2] => Array
(
[0] => 1
)

)
------------------------------


Merci d'avance pour votre aide

Guillaume

3 réponses

Avatar
Olivier Miakinen

[...]
<script language="javascript">var var1="toto";var var2="titi";var var310.4;var var4 = "";var var5 = "1";</script>
[...]

Dans cette page, je souhaiterais :

- Extraire les portions de code javascript qui ne contiennent que des
variables (en fait, la seule balise que j'ai laissé dans l'exemple
ci-dessus)

- Extraire de la chaîne trouvée, les paires clé=valeur trouvées

Tout cela en une seule expression régulière, en se basant sur le fait
que le masque "var cle=valeur;" peut être répété "à l'infini". :)


À moins d'utiliser les "assertions" (?=foo) et (?<bar) tu ne pourras pas
le faire en une seule expression rationnelle. En effet, lorsque tu
testes la balise <script> de début et la balise </script> de fin,
celles-ci sont "consommées" par ton expression pour trouver un couple
clé/valeur, et la recherche ne peut donc que continuer après le
</script>, ce qui n'est pas ce que tu veux.

Donc de deux choses l'une : soit tu abandonnes ton idée de le faire en
une seule passe et tu écris un code lisible et performant en deux passes
(1=obtenir le contenu de l'élément script, 2=en extraire les couples
clé/valeur) ; soit tu t'obstines en essayant d'utiliser les assertions,
et tu vas passer beaucoup de temps pour écrire un code illisible, très
gourmand en temps CPU, et très lent.

Choisis ton camp, camarade !

--
Olivier Miakinen
Non, monsieur le juge, je vous le jure : jamais je n'ai cité
Bruxelles dans ma signature.

Avatar
Guillaume
Merci pour ta réponse Olivier

Pendant mes recherches, j'ai bien essayé d'utiliser les assertions,
mais même avec ce procédé, je ne sais pas si ce que je voudrais
faire est réalisable !

Je pense me "résigner" à faire ce que je veux en deux passes :
1. extraction de tous les <script></script>
2. analyse de chaque résultat

Ce qui m'intéressait vraiment dans le fait de ne faire qu'une passe,
c'était de trouver une expression régulière capable d'analyser un
contenu avant de le retourner.

Mais bon, cela reste apparement (très) difficile ... ou impossible ?
Si quelqu'un a une idée ... je suis preneur ! ;)
Avatar
Olivier Miakinen

Pendant mes recherches, j'ai bien essayé d'utiliser les assertions,
mais même avec ce procédé, je ne sais pas si ce que je voudrais
faire est réalisable !


Je n'en suis pas sûr non plus. Tout ce que je sais, c'est que c'était
impossible sans elles.

Je pense me "résigner" à faire ce que je veux en deux passes :
1. extraction de tous les <script></script>
2. analyse de chaque résultat

Ce qui m'intéressait vraiment dans le fait de ne faire qu'une passe,
c'était de trouver une expression régulière capable d'analyser un
contenu avant de le retourner.


Si c'est un exercice de style pour le plaisir, alors je te suggère de
commencer par une syntaxe plus simple. Mettons par exemple la chaîne
"Da=b;a=b;a=b;F" avec un nombre variable de « a=b; » voire "Dx;x;x;F"
avec un nombre variable de « x; ».

Mais bon, cela reste apparement (très) difficile ... ou impossible ?
Si quelqu'un a une idée ... je suis preneur ! ;)


Une autre possibilité consiste à « tricher » en utilisant la fonction
preg_replace_callback() pour la phase 1, dans laquelle la callback
lancerait la phase 2 et complèterait un tableau global par effet
de bord. Autant dire que cette dernière solution est tout sauf
recommandable.

--
Olivier Miakinen
Non, monsieur le juge, je vous le jure : jamais je n'ai cité
Bruxelles dans ma signature.