Précédent   Forum des professionnels en informatique > PHP > Langage > Regex
Regex Forum d'entraide sur les expressions rationnelles PHP. Avant de poster -> FAQ regex, Cours de regex et Sources de regex
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 22/11/2007, 15h17   #1
Rédacteur/Modérateur
 
Avatar de N1bus
 
Inscription : janvier 2003
Messages : 2 018
Détails du profil
Informations personnelles :
Âge : 47
Localisation : France, Charente Maritime (Poitou Charente)

Informations forums :
Inscription : janvier 2003
Messages : 2 018
Points : 1 992
Points : 1 992
Par défaut Extraire du texte avec div imbriqués

Bonjour,

J'ai un texte comme celui-ci :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
<div class="dscg">
<p>CR&Eacute;ATION D&rsquo;ENTREPRISE</p>
<div class="encadre-dossier">&bull; L&rsquo;Ab&eacute;c&eacute;daire de la d&eacute;cision pour cr&eacute;er son entreprise <br />
&bull; Cr&eacute;er, un acte accessible &agrave; tous <br />
&bull; Comment former davantage d&rsquo;entrepreneurs en France ? <br />
&bull; Changer de statut social <br />
&bull; Envisager une augmentation de capital dans une SARL</div>
<p>&nbsp;</p>
<div class="encadre-dossier"><span class="soustitre-dossier">L&rsquo;AB&Eacute;C&Eacute;DAIRE DE LA D&Eacute;CISION POUR CR&Eacute;ER SON ENTREPRISE </span><br />
Avant d&rsquo;&ecirc;tre une s&eacute;rie d&rsquo;actes techniques et administratifs, la cr&eacute;ation d&rsquo;entreprise est d&rsquo;abord un choix de vie qui engage l&rsquo;individu dans l&rsquo;int&eacute;gralit&eacute; de sa personnalit&eacute; mais aussi sa famille et ses biens. Elle suppose au d&eacute;part une formidable envie d&rsquo;oser, coupl&eacute;e &agrave; un fort esprit de responsabilit&eacute;. Cette aventure requiert une bonne dose de courage pour aller surfer sur les innombrables vagues de contraintes et d&rsquo;&eacute;cueils sociaux, &eacute;conomiques, administratifs, fiscaux, financiers, parsemant la trajectoire de tout futur dirigeant. Ce dossier n&rsquo;est pas un guide technique mais seulement un premier &laquo;poteau indicateur&raquo; destin&eacute; &agrave; s&rsquo;orienter dans le vaste espace entrepreneunarial.</div>
<p>&nbsp;&nbsp;A comme Aides financi&egrave;res</p>
<p>&nbsp;</p>
<p>Aides financi&egrave;res : Il existe une grande diversit&eacute; d&rsquo;aides financi&egrave;res. Chaque r&eacute;gion dispose de son propre dispositif sachant que par principe : <br />
&bull; Les aides n&rsquo;arrivent souvent que plusieurs mois apr&egrave;s la cr&eacute;ation. <br />
&bull; Il faut &ecirc;tre capable de s&rsquo;en passer, voire de fonctionner sans elle. <br />
&bull; Elles ne doivent repr&eacute;senter qu&rsquo;une partie infime du plan de financement.</p>
<p>&nbsp;</p>
</div>
Ce texte est saisi par l'utilisateur avec FCKEditor. Lorsqu'il sélectionne une partie du texte et lui applique le style "dscg" , cela encapsule le texte sélectionné entre les balises <div class="dscg"> et </div>

Et je souhaite récupérer le texte contenu entre <div class="dscg"></div>

Pour l'instant j'y arrive avec ceci :

Code :
1
2
3
4
5
6
 
//$doTexte = le texte récupéré en $_POST via le formulaire de saisie
preg_match_all('#<div class="dscg">(.*[<div .*?</div>]*)</div>#s', $doTexte, $m);
 
//$x_doResume = partie du texte à récupérer puis envoyer à BDD   
$x_doResume = mysql_real_escape_string($m[1][0]);

Le problème que je rencontre :
Si l'utilisateur s'embrouille les pinceaux avec les styles ou les formats (pour ceux qui connaissent FCKEditor ...), il se peut que certaines balises <div> se chevauchent ou soient incohérentes. On peut finalement arriver à un texte comme ceci :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
 
<div class="dscg"
// 
// du texte
//
<div class="encadre-dossier">
// autre texte
</div>
// autre texte
<div>
// autre texte
</div>
J'ai donc ici une balise ouvrante <div> en trop.
Là, ma Regex ne fonctionne plus correctement.


Le but de cette opération :
Je précise que le texte devant être extrait sera affiché gratuitement, le texte entier sur abonnement.

Afin que l'administrateur saisisse et formate le texte en une seule fois sans avoir à re saisir et reformater dans un autre champ le contenu gratuit, il selectionne la portion de code et lui applique le style "dscg" (ce qui crée en fait les balises <div class="dscg"></div>)

Avez vous une soluce pour traiter la récursivité des balises <div> (même en cas de chevauchement) ?
Ma regex est-elle correcte ?

Merci à tous.
N1bus est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/11/2007, 18h16   #2
Rédacteur
 
Avatar de Yogui
 
Homme Guillaume Rossolini
Directeur technique
Inscription : février 2004
Messages : 13 720
Détails du profil
Informations personnelles :
Nom : Homme Guillaume Rossolini
Localisation : France

Informations professionnelles :
Activité : Directeur technique

Informations forums :
Inscription : février 2004
Messages : 13 720
Points : 17 355
Points : 17 355
Salut

Les regex ne sont pas adaptées à ton problème. Il faudrait presque adopter une approche DOM, mais les regex ne règleront jamais correctement un problème de HTML ou de XML.

Exemple :
Code :
1
2
3
4
5
6
7
8
9
<pre>
<?php
 
$str = '[div]§ 1[div]§ 2[div]§ 3[/div][/div][/div]';
preg_match_all(\[div\](.*)\[/div\]¤', $str, $matches);
print_r($matches);
 
?>
</pre>
Code :
1
2
3
4
5
6
7
8
9
<pre>
<?php
 
$str = '[div]§ 1[div]§ 2[div]§ 3[/div][/div][/div]';
preg_match_all(\[div\](.*?)\[/div\]¤', $str, $matches);
print_r($matches);
 
?>
</pre>
Tu peux essayer avec de la récursivité, mais je ne te dis pas comment ça doit consommer des performances...
__________________
Mes articles - Zend Certified Engineer (PHP + Zend Framework)
Ressources PHP - Ressources Zend Framework
Yogui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/11/2007, 23h43   #3
Rédacteur/Modérateur
 
Avatar de N1bus
 
Inscription : janvier 2003
Messages : 2 018
Détails du profil
Informations personnelles :
Âge : 47
Localisation : France, Charente Maritime (Poitou Charente)

Informations forums :
Inscription : janvier 2003
Messages : 2 018
Points : 1 992
Points : 1 992
Merci Yogui, mais je n'ai pas compris :

Ton code permet juste de détecter le contenu de 3 div maxi ?
c'est ça ?


Dans le cas qui m'interresse, je dois détecter le premier div qui a la class="dscg" (c'est impératif), et eventuellement inclure les autres div (il peut y en avoir + de 3 : c'est l'utilisateur qui sélectionne le texte ....)

Aussi bien, il peut n'y avoir aucun problème, mais ceci n'est pas fiable à 100%

J'ai peut-être une autre solution :
Insérer une "balise" maison en début et en fin de sélection

Code :
1
2
3
4
5
6
 
[[!!debut-contenu-gratuit!!]]
//
//
//
[[!!fin-contenu-gratuit!!]]
Ces balises seraient effacées à l'affichage.

Le problème :
Je dois faire en sorte que l'administrateur puisse insérer ces balises en 1 clic . il ne doit pas avoir à les écrire lui-même.

Le texte délimité doit apparaitre avec un style particulier dans le textarea de FCKEditor afin de le visualiser immédiatement (fond jaune pâle avec bordure tirets gris = le style "dscg")

- il faut que je crée une fonction dans FCKEditor avec un nouveau bouton qui fonctionnera un peu comme lorsqu'on met en gras (balise entrante + texte sélectionné + balise fermante).

- il faut un deuxieme bouton pour supprimer ces balises , le cas échéant (en cas d'erreur de l'admin)


Ainsi avec une simple regex, je pourrai récupérer le contenu entre les balises en m'affranchissant d'éventuelles autres balises standard qui seraient incluses.

Note :
La solution qui consisterait à recopier le contenu gratuit dans un autre champ n'est pas valable dans la mesure où l'administrateur devrait également mettre en forme le contenu gratuit et le texte entier (FCKEditor nettoie le texte à l'insertion donc un copier coller tu texte mis en forme ne marche pas dans ce cas).
Le client veut que ça fonctionne en un clin d'oeil et ne veut pas saisir 2 fois le texte.
N1bus est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/11/2007, 02h59   #4
Rédacteur
 
Avatar de Yogui
 
Homme Guillaume Rossolini
Directeur technique
Inscription : février 2004
Messages : 13 720
Détails du profil
Informations personnelles :
Nom : Homme Guillaume Rossolini
Localisation : France

Informations professionnelles :
Activité : Directeur technique

Informations forums :
Inscription : février 2004
Messages : 13 720
Points : 17 355
Points : 17 355
Sans utiliser la récursivité (légèrement complexe à maîtriser), les regex te permettent l'un ou l'autre parmi :
  • Avoir depuis le premier tag ouvrant jusqu'au premier fermant ;
  • Avoir le premier tag ouvrant jusqu'au dernier fermant.
Par contre, si tu maîtrises la récursivité dans les regex, tu peux faire comme bon te semble.
Si je ne suis pas assez clair, le plus simple est que tu fasses des essais toi-même à partir de l'exemple ci-dessus. Expliquer avec des mots serait complexe à écrire (pour moi) et pénible à lire (pour toi) :/
__________________
Mes articles - Zend Certified Engineer (PHP + Zend Framework)
Ressources PHP - Ressources Zend Framework
Yogui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/11/2007, 09h53   #5
Rédacteur/Modérateur
 
Avatar de N1bus
 
Inscription : janvier 2003
Messages : 2 018
Détails du profil
Informations personnelles :
Âge : 47
Localisation : France, Charente Maritime (Poitou Charente)

Informations forums :
Inscription : janvier 2003
Messages : 2 018
Points : 1 992
Points : 1 992
Ok, je vais regarder ça.
Merci
N1bus est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/11/2007, 11h23   #6
Rédacteur/Modérateur
 
Avatar de N1bus
 
Inscription : janvier 2003
Messages : 2 018
Détails du profil
Informations personnelles :
Âge : 47
Localisation : France, Charente Maritime (Poitou Charente)

Informations forums :
Inscription : janvier 2003
Messages : 2 018
Points : 1 992
Points : 1 992
Bon, j'ai résolu le problème :


Le problème des div imbriqués était causé par un autre "style" qui générait en fait un div (au lieu du span habituel) dans FCKEditor.

Cet autre style avait pour fonction d'encadrer une partie de texte sans avoir à le mettre dans un tableau d'1 cellule

J'ai remis ce style avec un span et display:block ..... (le span étant par nature display:inline )

Ce qui fait que maintenant, je ne peux plus avoir de div à l'interieur de <div class="dscg"></div>. je n'aurai que des span

La regex que j'utilise :
Code :
1
2
3
4
5
6
 
//$doTexte = le texte récupéré en $_POST via le formulaire de saisie
preg_match_all('¤<div class="dscg">(.*)</div>¤s', $doTexte, $m);
 
//$x_doResume = partie du texte à récupérer puis envoyer à BDD 
$x_doResume = mysql_real_escape_string($m[1][0]);
ça fonctionne avec IE (6 /7 ) et FF , par contre je viens de m'apercevoir que FCKeditor ne fonctionne pas avec Safari ......... (mon client est sur Mac )

[EDIT]
Bon, j'ai vu FF pour Mac : je l'ai installé sur mon iMac = c'est nickel (ouf !!)
par contre IE pour mac c'est fini http://www.microsoft.com/france/mac/ie/default.mspx
[/EDIT]

Merci à tous.
N1bus est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 12h27.


 
 
 
 
Partenaires

Hébergement Web