Quelle regex php pour sélectionner du html ?

WRInaute accro
Voilà

Je souhaite :

Lignes par lignes.

Sélectionner toutes les balises html, avec leurs attributs éventuels ( pas besoin de faire celà en une seule fois ),

sélectionner aussi les codes php dans le html, ainsi que les scripts et noscripts.

Ceci en une seule regex php.

Le code suivant me sélectionne les <?php , ?>, <script.*> </script>, <noscript.*> et </noscript> , rien d'autre.

Le problème vient probablement des deux regex ( première et troisième ) ci-dessous, qui sont censée sélectionner tous caractères sauf les <?php, ?>, <script etc...

J'ai essayé (.*) à leurs places, mais la sélection déborde et après <?php , ?> ... le reste de la ligne est en trop.

Il faut sélectionner : tout sauf un \? suivi de >, et tout sauf un < , suivi de \?(php)? ou de (no)?script.*>, ou de /(no)?script>.

C'est à-dire, plusieurs negative lookahead alternatifs.

Le nombre d'occurrences doit être : de zéro à infini.

Faut-il faire aussi des negative lookbehind pour éviter les caractères non désirés ?

Merci beaucoup de votre aide.


PHP:
        if(preg_match("{

        ((?:(?:<(?!(?:no)?script.*>))|(?:<(?!\/(?:no)?script>))|(?:<(?!\?(php)?))|(\?(?!>)))*?)     // negative lookahead

        ((?:<(?:no)?script.*>|<\/(?:no)?script>|<\?(php)?|\?>)?)          // sélection code et scripts

        ((?:(?:<(?!(?:no)?script.*>))|(?:<(?!\/(?:no)?script>))|(?:<(?!\?(php)?))|(\?(?!>)))*?)    // negative lookahead


        }", $fdata, $output)) {
 
WRInaute impliqué
Ne pas faire de regex pour traiter du HTML (ou du SGML de façon générale). Y'a plein d'autres outils, mieux faits, plus efficaces, pour parser du HTML.

En regex, gérer les passages commentés, ou les caractères d'échappement (notamment) est une horreur. Et puis dès que ce n'est pas parfaitement conforme à la norme, ça va pas coller (HTML est plus permissif que ne le sera une regex), sans parler de toutes les variations et exceptions. Par exemple, la valeur d'un attribut est souvent entre guillemets doubles, mais il peut l'être entre guillemets simples, voir sans guillemets s'il n'y a pas d'espaces.

Ceci étant posé, j'adore les regex. Et j'en utilise parfois pour faire des choses qu'il ne faudrait pas (c'est pas bien, mais c'est plus fort que moi). Toutefois, je ne suis pas certain d'avoir compris la demande.

La regex suivante peut constituer une base, il retourne les balises ouvrantes avec ses attributs et valeurs (mais pas leur contenu) :
Code:
<(?P<tag>[a-z]+)( ([a-z-]+)(=("[^"]*"|[^ >]+|'[^']*'))?)* ?\/?>

Bon, en vrai c'est juste une base, il faudrait la tester par rapport à un échantillon de tes données. Il faut bien avoir en tête qu'il doit y avoir plein d'hypothèses qu'elle ne gère pas (typiquement les caractères d'échappement). Une fois encore, les regex ne sont pas faites pour parser du HTML (même si les regex c'est génial).
 
WRInaute passionné
Dans quelques jours la vague d'indignation va apparaître, à la sortie de iOS 17.4, pour l'instant peu de gens sont au courant.
Dur en particulier les entreprises qui avaient convaincu leurs clients de faire une PWA pour réduire les coûts par rapport à une native.
Apple ne se sentait sans doute pas suffisamment détesté des développeurs comme ça.
 
WRInaute passionné
@rick38 oui j'avais vu ça. Mais ce n'est pas encore trop grave il suffit de convertir avec Cordova ou similaire (je fais de moins en moins de Web donc je suis en train de perdre le train en marche).
Oui on peut encapsuler la pwa pour en fait une app dispo dans un store (je le fais pour Google et Microsoft vu que c'est gratuit), mais ça demande à s'embêter avec ce process, et à convaincre les gens d'aller télécharger l'app... (et sur l'App Store, 99 €/an et encore il faut qu'ils l'acceptent...)
Alors que jusqu'ici il suffisait d'envoyer un raccourci du site sur le home screen.

Bon j'ai confiance que d'ici quelques années Apple fasse un truc pour les réautoriser, ils auront trop de pression.
 
WRInaute passionné
Je ne sais pas si c'est parce que je vieillis mais les années me semblent de plus en plus courtes.
https://www.igen.fr/ios/2024/03/surprise-ios-174-va-finalement-maintenir-les-pwa-en-europe-142251
Arf, le tollé a été trop grand, des amateurs chez Apple...
Tant mieux. Ils se sont soucié un peu de leur image sur ce coup-là.
Par contre ils continueront de forcer l'utilisation de webkit.
L'UE pourrait demander à ce que le navigateur par défaut soit utilisé, à ce moment-là Apple pourrait à nouveau retirer la fonctionnalité.
 
Dernière édition:
WRInaute accro
Excusez-moi

J'ai programmé depuis longtemps une librairie php de parsing html, sur le modèle de la librairie native xml.

J'ai vaguement commencé à isoler les blocs et balises du type : <?(php)? , ?>, <(?:no)?script.*> et </(?:no)?script>.

Je les met à partir de chaque lignes du fichier lu, dans une array que je parcours en alimentant des variables ( $is_script, $is_code, $type_code ), qui me permettront de traiter/parser correctement ces données.

Le problème principal est que du <script> ... </script> peut être imbriqué dans du <?php ... ?> ou inversement, ce qui m'obligera à mémoriser les parsings imbriqués, pour les insérer dans les données autour, au moment où celles-ci sont parsées.

Dur dur...
 
WRInaute accro
Bonjour

Je dois faire une regex :

Qui matche une chaîne de n'importe quels caractères, ne comportant pas :

\?>

ni

<(no)?script[^>]*>

ni

</(no)?script>

ni

<\?(php)?

Avec deux negative lookahead ?

Merci beaucoup de votre aide.
 
WRInaute accro
Bon, bon...

Cà marche, en éliminant les résultats vides.


Ligne parsée :
***************

PHP:
    $fdata = "apol>|?u<?phpbne<aou?>sb</noscript>apl<usb<script text=\"Javascript\">plu<sbag";


Résultat :
*********

PHP:
Array
(
    [0] => apol>|?u
    [1] => <?php
    [2] => bne<aou
    [3] => ?>
    [4] => sb
    [5] => </noscript>
    [6] => apl<usb
    [7] => <script text="Javascript">
    [8] => plu<sbag
)

Regex :
********

PHP:
if(preg_match_all("{((<\?(php)?|<(no)?script[^>]*>|</(no)?script>|\?>)|(([^<\?]*((<(?!(\?(php)?|script|noscript|/script|/noscript)))|(\?(?!>))))?([^<\?]*)))}", $fdata, $output,  PREG_PATTERN_ORDER)) {



}
 
WRInaute accro
Bonjour

J'ai fait une erreur.

Je n'ai pas tenu compte du fait qu'il puisse y avoir des contenus en php devant être interprétés éventuellement comme code html, et aussi des fonctions php pouvant le cas échéant, rendre du html.

J'envisage de ne faire que de la détection de balises html, en loguant par fichiers/lignes, les cas litigieux ( attributs dont les valeurs ne sont pas entourées par des quotes doubles ).

Celà reviendrait à tout bonnement utiliser telle quelle ma librairie de parsing html sans séparer scripts et codes du html, après adaptation de la lecture des balises et attributs.

Après, à moi de corriger manuellement les cas litigieux.

Ouf de ouf.
 
WRInaute accro
Voilà voilà

431 fichiers php traités.

Fragment de log obtenu :

Code:
Erreur dans fichier : /var/www/html/traduct/lescourses.com/aboprono.php at line : 36
<td colspan=2>

Erreur dans fichier : /var/www/html/traduct/lescourses.com/aboprono.php at line : 43
<img width=21>

Erreur dans fichier : /var/www/html/traduct/lescourses.com/aboprono.php at line : 43
<img height=25>

Cà détecte les attributs des balises dont les valeurs ne sont pas entourées par des quotes doubles.

Il y a 3041 erreurs, dont un grand nombre pour une balise/plusieurs attributs.

Je reconnais qu'après il faut se farcir les corrections manuellement.
 
WRInaute accro
Pardon

A partir de ce que j'ai fait, j'envisage de produire les fichiers php initiaux , de format identique , et corrigés entièrement automatiquement.

Le fichier de log ci-dessus : tmp_log.txt

Pour chaque numéros de lignes identiques d'un même fichier :

Mettre le fichier lignes par lignes dans une variable indicée,

placer des quotes doubles autour de la valeur du token cible,

remplacer dans la variable indicée, le token source par le token cible.

Pour celà, fixer les offsets début/fin du token source.

Après, le site cible sera corrigé, il ne restera plus à qu'essayer de détecter les erreurs résiduelles.

Merci beaucoup de vos suggestions.
 
WRInaute accro
Plus facile.

98 fichiers php en erreur.

Balises entières.

Je ne sais pas trop quel algorithme utiliser pour mapper les tokens sources lus dans tmp_new_log.txt et corrigés vers les tokens cibles des scripts php.

Les balises/attributs avant correction, sont identiques aux tokens cibles.

Donc : str_replace() ?

Merci beaucoup de votre aide.




Code:
  tmp_new_log.txt

Erreur dans fichier : /var/www/html/traduct/lescourses.com/aboprono.php at line : 36
<td colspan=2>

Erreur dans fichier : /var/www/html/traduct/lescourses.com/aboprono.php at line : 43
<img src="images/hg.gif" width=21 height=25>

Erreur dans fichier : /var/www/html/traduct/lescourses.com/aboprono.php at line : 45
<img src="images/hd.gif" width=26 height=25>
.
 
WRInaute accro
Voilà les regex.

Calculées automatiquement.

Y- a plus qu'à.

PHP_IN est : <?php

PHP_OUT est : ?>

Il suffit de remplacer la regex par le token : après.


Code:
Erreur dans fichier : aboprono.php at line : 91
regex : {<td[ ]+colspan=2[ ]+class=formtxt[ ]+align=center>}i
avant : <td colspan=2 class=formtxt align=center>
après : <td colspan="2" class="formtxt" align="center">

Erreur dans fichier : aboprono.php at line : 91
regex : {<a[ ]+href='PHP_IN[ ]+echo[ ]+WEB_URL;[ ]+PHP_OUT/javascript:stasub(document.form1,'desinscription');'>}i
avant : <a href='PHP_IN echo WEB_URL; PHP_OUT/javascript:stasub(document.form1,'desinscription');'>
après : <a href="PHP_IN echo WEB_URL; PHP_OUT/javascript:stasub(document.form1,'desinscription');">

Erreur dans fichier : aboprono.php at line : 116
regex : {<img[ ]+src="images/bg.gif"[ ]+width=21[ ]+height=29>}i
avant : <img src="images/bg.gif" width=21 height=29>
après : <img src="images/bg.gif" width="21" height="29">

Erreur dans fichier : aboprono.php at line : 118
regex : {<img[ ]+src="images/bd.gif"[ ]+width=26[ ]+height=29>}i
avant : <img src="images/bd.gif" width=26 height=29>
après : <img src="images/bd.gif" width="26" height="29">
 
WRInaute accro
Voilà voilà

Ces quelques lignes...

Le fichier écrit est produit automatiquement.

Le formatage du fichier source est préservé.

Je n'ai plus qu'à tester le soft pour tout lescourses.com.


Code:
Erreur dans fichier : aboprono.php at line : 36
avant : <td colspan=2>
regex :  colspan=2
après :  colspan="2"
fdata_write_avant :     <td colspan=2><?php require("top.inc.php"); ?></td>
fdata_write_après :     <td colspan="2"><?php require("top.inc.php"); ?></td>

Erreur dans fichier : aboprono.php at line : 43
avant : <img src="images/hg.gif" width=21 height=25>
regex :  src="images/hg.gif" width=21 height=25
après :  src="images/hg.gif" width="21" height="25"
fdata_write_avant :             <td><img src="images/hg.gif" width=21 height=25></td>
fdata_write_après :             <td><img src="images/hg.gif" width="21" height="25"></td>

Erreur dans fichier : aboprono.php at line : 45
avant : <img src="images/hd.gif" width=26 height=25>
regex :  src="images/hd.gif" width=26 height=25
après :  src="images/hd.gif" width="26" height="25"
fdata_write_avant :             <td><img src="images/hd.gif" width=26 height=25></td>
fdata_write_après :             <td><img src="images/hd.gif" width="26" height="25"></td>

Erreur dans fichier : aboprono.php at line : 77
avant : <td width=20% align="right" class="txtbox">
regex :  width=20% align="right" class="txtbox"
après :  width="20%" align="right" class="txtbox"
fdata_write_avant :                             <td width=20% align="right" class="txtbox">nom</td>
fdata_write_après :                             <td width="20%" align="right" class="txtbox">nom</td>
 
WRInaute accro
Voilà c'est fait.

lescourses.com (sur mon ordinateur ), a eu toutes les valeurs de ses attributs entourés comme il faut par des quotes doubles, ou antislashes/quotes doubles.

Tous les scripts compilent, et le site fonctionne entièrement.

Je n'ai plus qu'à adapter les balises/attributs/valeurs sur mon site de la même façon.

Tout a été automatique, si ce n'est trois/quatre scripts à reprendre manuellement, cause token imprévisible.

Bien à vous.
 
Discussions similaires
Haut