Les archives de FluxBB.fr
Vous n'êtes pas identifié(e).
J'ai besoin d'aide, j'essai de faire une fonction qui transformerait le XHTML en BBcode. Oui mais voilà j'en chie
Ci-dessou ce que j'ai fait ce soir. Si quelqu'un peu m'aider à améliorer cette fonction... ça serait cool.
/*
* EXPERIMENTAL
*
* @function simpleXhtml2bbcode
*
* Transforme les balises XHTML en BBcode
*
* @param string str Chaîne à convertir
* @return string
*/
function simpleXhtml2bbcode($str)
{
// des couleurs ?
$str = preg_replace(
'#<span\s*style="color:\s*([a-zA-Z]*|\#?[0-9a-fA-F]{6})\s*;?\s*">(.*?)</span>#s',
'[color=$1]$2[/color]', $str);
// lien email
$str = preg_replace(
'#<a\s*href="mailto:(.*?)">(.*?)</a>#s',
'[email=$1]$2[/email]', $str);
// lien email avec attribut langue ; si quelqu'un arrive
// à fusionner ça avec la précédente je suis preneur...
$str = preg_replace(
'#<a\s*hreflang="[a-zA-Z]*"\s*href="mailto:(.*?)">(.*?)</a>#s',
'[email=$1]$2[/email]', $str);
// lien
$str = preg_replace(
'#<a\s*href="(.*?)">(.*?)</a>#s',
'[url=$1]$2[/url]', $str);
// lien avec attribut langue, pareil qu'au dessus..
$str = preg_replace(
'#<a\s*hreflang="[a-zA-Z]*"\s*href="(.*?)">(.*?)</a>#s',
'[url=$1]$2[/url]', $str);
// autres remplacements
$str = preg_replace('#<strong.*?>(.*?)</strong>#s', '[b]$1[/b]', $str);
$str = preg_replace('#<em.*?>(.*?)</em>#s', '[i]$1[/i]', $str);
$str = preg_replace('#<blockquote.*?>(.*?)</blockquote>#s', '[quote]$1[/quote]
', $str);
$str = preg_replace('#<li.*?>(.*?)</li>#s', "* $1", $str);
$str = preg_replace('#<p.*?>(.*?)</p>#s', "$1\n\n", $str);
$pattern = array('<br />', ' ', ' ', ' ');
$replace = array("\n", "\t", ' ', ' ');
$str = str_replace($pattern, $replace, $str);
// on vire le HTML qui reste
$str = strip_tags($str);
# ouais, ok c'est pas terrible tout ça, mais les regex et moi ça fait 12
# et c'est mieux que rien ! ou disons que c'est un début
return $str;
}Hors ligne
Yop, essaye avec ceci, ça devrait aller
:
/*
* EXPERIMENTAL
*
* @function simpleXhtml2bbcode
*
* Transforme les balises XHTML en BBcode
*
* @param string str Chaîne à convertir
* @return string
*/
function simpleXhtml2bbcode($str)
{
// des couleurs ?
$str = preg_replace(
'#<span\s*style="color:\s*([a-zA-Z]*|\#?[0-9a-fA-F]{6})\s*;?\s*">(.*?)</span>#s',
'[color=$1]$2[/color]', $str);
// lien email (avec attribut langue -> facultatif)
$str = preg_replace(
'#<a(?:\s*hreflang="[a-zA-Z]*")?\s*href="mailto:(.*?)">(.*?)</a>#s',
'[email=$1]$2[/email]', $str);
// lien (avec attribut langue -> facultatif)
$str = preg_replace(
'#<a(?:\s*hreflang="[a-zA-Z]*")?\s*href="(.*?)">(.*?)</a>#s',
'[url=$1]$2[/url]', $str);
// autres remplacements
$str = preg_replace('#<strong.*?>(.*?)</strong>#s', '[b]$1[/b]', $str);
$str = preg_replace('#<em.*?>(.*?)</em>#s', '[i]$1[/i]', $str);
$str = preg_replace('#<blockquote.*?>(.*?)</blockquote>#s', '[quote]$1[/quote]
', $str);
$str = preg_replace('#<li.*?>(.*?)</li>#s', "* $1", $str);
$str = preg_replace('#<p.*?>(.*?)</p>#s', "$1\n\n", $str);
$pattern = array('<br />', ' ', ' ', ' ');
$replace = array("\n", "\t", ' ', ' ');
$str = str_replace($pattern, $replace, $str);
// on vire le HTML qui reste
$str = strip_tags($str);
# ouais, ok c'est pas terrible tout ça, mais les regex et moi ça fait 12
# et c'est mieux que rien ! ou disons que c'est un début
return $str;
}Pour rendre facultatif un paramètre, j'ai mis entre parenthèse ce dernier, avec un ? (signifiant présent ou pas). Les deux caractères ?: signifient "ne pas mettre en variable". 
Dernière modification par nicolas2k10 (26-08-2006 00:39:40)
Hors ligne
ouaip ça marche, bien ouej ! merci 
maintenant faut compléter et affiner, je pense qu'il y a moyen d'améliorer cette fonction, mais je me suis fait mal ce soir avec ça
et c'est déjà un bon début
si tu veut continuer à améliorer, hésite pas ; le but est de fournir un texte en XHTML et d'en faire un post sur les forums
en tout cas merci, je ne connaissais pas du tout ce ?:
Hors ligne
Je dirais même plus (pour plus de rapidité)
:
/*
* EXPERIMENTAL
*
* @function simpleXhtml2bbcode
*
* Transforme les balises XHTML en BBcode
*
* @param string str Chaîne à convertir
* @return string
*/
function simpleXhtml2bbcode($str)
{
$pattern = array(
// couleurs
'#<span\s*style="color:\s*([a-zA-Z]*|\#?[0-9a-fA-F]{6})\s*;?\s*">(.*?)</span>#s',
// liens (avec attribut langue -> facultatif)
'#<a(?:\s*hreflang="[a-zA-Z]*")?\s*href="mailto:(.*?)">(.*?)</a>#s', // e-mail
'#<a(?:\s*hreflang="[a-zA-Z]*")?\s*href="(.*?)">(.*?)</a>#s', // liens simples
// autres remplacements
'#<strong.*?>(.*?)</strong>#s',
'#<em.*?>(.*?)</em>#s',
'#<blockquote.*?>(.*?)</blockquote>#s',
'#<li.*?>(.*?)</li>#s',
'#<p.*?>(.*?)</p>#s'
);
$replace = array(
// couleurs
'[color=$1]$2[/color]',
// liens
'[email=$1]$2[/email]', // e-mail
'[url=$1]$2[/url]', // liens simples
// autres remplacements
'[b]$1[/b]',
'[i]$1[/i]',
'[quote]$1[/quote]
',
"* $1",
"$1\n\n"
);
$str = preg_replace($pattern, $replace, $str);
// espacements et retours de ligne
$pattern = array('<br />', ' ', ' ', ' ');
$replace = array("\n", "\t", ' ', ' ');
$str = str_replace($pattern, $replace, $str);
// on vire le HTML qui reste
$str = strip_tags($str);
return $str;
}Le ?: est bien pratique lorsqu'on veut entourer une partie du motif sans mettre ce résultat dans une variable (donc ici, la 1ère parenthèse est dite "non-capturante" mais celle qui suit (qui aurait d'ailleurs pu être incluse dedans car c'est l'ordre d'ouverture qui compte), elle, l'est et commence donc à $1). 
Dernière modification par nicolas2k10 (26-08-2006 01:10:08)
Hors ligne
les grands esprits se rencontre
je venais pour poster ceci :
/**
* EXPERIMENTAL
*
* @function simpleXhtml2bbcode
*
* Transforme les balises XHTML en BBcode
*
* @param string str Chaîne à convertir
* @return string
*/
function simpleXhtml2bbcode($str)
{
$pattern = array(
'#<span\s*style="color:\s*([a-zA-Z]*|\#?[0-9a-fA-F]{6})\s*;?\s*">(.*?)</span>#s',
'#<a(?:\s*hreflang="[a-zA-Z]*")?\s*href="mailto:(.*?)">(.*?)</a>#s',
'#<a(?:\s*hreflang="[a-zA-Z]*")?\s*href="(.*?)">(.*?)</a>#s',
'#<strong.*?>(.*?)</strong>#s',
'#<em.*?>(.*?)</em>#s',
'#<blockquote.*?>(.*?)</blockquote>#s',
'#<li.*?>(.*?)</li>#s',
'#<p.*?>(.*?)</p>#s',
);
$replace = array(
'[color=$1]$2[/color]',
'[email=$1]$2[/email]',
'[url=$1]$2[/url]',
'[b]$1[/b]',
'[i]$1[/i]',
'[quote]$1[/quote]
',
"* $1",
"$1\n\n",
);
$str = preg_replace($pattern, $replace, $str);
$pattern = array('<br />', ' ', ' ', ' ');
$replace = array("\n", "\t", ' ', ' ');
$str = str_replace($pattern, $replace, $str);
return strip_tags($str);
}Hors ligne
tiens tu va peut-être pouvoir me répondre, au début pour l'élément <a> et l'attribut hreflang j'avais fait comme par exemple pour l'élément <strong> quelque chose comme ça [c]'#<a.*?href="(.*?)">(.*?)</a>#s',[/c] mais ça ne fonctionnait pas ; saurait tu me dire pourquoi ? même si ta solution est tout à fait élégante et fonctionne très bien 
parce que là le problème en fait c'est que si les éléments ont des attributs supplémentaires, genre [c]style="..."[/c] ou [c]class=".."[/c] etc. la transformation ne s'effectue pas
donc pour les éléments sans attributs comme <strong> ou <em> les [c]'#<strong.*?>(.*?)</strong>#s'[/c] et [c]'#<em.*?>(.*?)</em>#s'[/c] semblent fonctionner mais pour les liens c'est plus compliqué car il peut y avoir d'autres attributs de chaques côtés de l'attribut [c]href[/c]
Hors ligne
Le ?: est bien pratique lorsqu'on veut entourer une partie du motif sans mettre ce résultat dans une variable (donc ici, la 1ère parenthèse est dite "non-capturante" mais celle qui suit (qui aurait d'ailleurs pu être incluse dedans car c'est l'ordre d'ouverture qui compte), elle, l'est et commence donc à $1).
oui c'est ce que j'avais cru comprendre et regardant ton code ; par contre je ne suis pas sur de comprendre ce que tu veut dire là : (qui aurait d'ailleurs pu être incluse dedans car c'est l'ordre d'ouverture qui compte)
Hors ligne
Es-tu sûr ?
<?php
$str = '<a style="xxx" href="xxx"></a>';
$str = preg_replace('#<a.*?href="(.*?)">(.*?)</a>#s', 'test', $str);
echo $str;
?>m'affiche bien test 
oui c'est ce que j'avais cru comprendre et regardant ton code ; par contre je ne suis pas sur de comprendre ce que tu veut dire là : (qui aurait d'ailleurs pu être incluse dedans car c'est l'ordre d'ouverture qui compte)
Je voulais simplement dire que :
(?:xxx=(aaaaaaaa)?)?(cccc)?
$1 vaudra aaaaaaaa
$2 vauda cccc
le contenu de la parenthèse ?: n'a pas été mis en variable SAUF si une sous-partie est elle entre parenthèse capturante (ici aaaaaaaa).
Donc dans l'ordre d'ouverture :
on trouve d'abord ( mais suivi de ?: donc on prend pas, puis ( non suivi de ?: op on prend dans $1, etc. 
Un site que je ne serai que trop te conseiller est www.expreg.com 
Dernière modification par nicolas2k10 (26-08-2006 01:27:25)
Hors ligne
oui, avec la fonction suivante :
/**
* EXPERIMENTAL
*
* @function simpleXhtml2bbcode
*
* Transforme les balises XHTML en BBcode
*
* @param string str Chaîne à convertir
* @return string
*/
function simpleXhtml2bbcode($str)
{
$pattern = array(
// couleurs
'#<span\s*style="color:\s*([a-zA-Z]*|\#?[0-9a-fA-F]{6})\s*;?\s*">(.*?)</span>#s',
// liens (avec attribut langue -> facultatif)
// '#<a(?:\s*hreflang="[a-zA-Z]*")?\s*href="mailto:(.*?)">(.*?)</a>#s', // e-mail
// '#<a(?:\s*hreflang="[a-zA-Z]*")?\s*href="(.*?)">(.*?)</a>#s', // liens simples
'#<a.*?href="mailto:(.*?)">(.*?)</a>#s',
'#<a.*?href="(.*?)">(.*?)</a>#s',
// autres remplacements
'#<strong.*?>(.*?)</strong>#s',
'#<em.*?>(.*?)</em>#s',
'#<blockquote.*?>(.*?)</blockquote>#s',
'#<li.*?>(.*?)</li>#s',
'#<p.*?>(.*?)</p>#s'
);
$replace = array(
// couleurs
'[color=$1]$2[/color]',
// liens
'[email=$1]$2[/email]', // e-mail
'[url=$1]$2[/url]', // liens simples
// autres remplacements
'[b]$1[/b]',
'[i]$1[/i]',
'[quote]$1[/quote]
',
"* $1",
"$1\n\n"
);
$str = preg_replace($pattern, $replace, $str);
// espacements et retours de ligne
$pattern = array('<br />', ' ', ' ', ' ');
$replace = array("\n", "\t", ' ', ' ');
$str = str_replace($pattern, $replace, $str);
// on vire le HTML qui reste
$str = strip_tags($str);
return $str;
}le code suivant :
Voici donc un <a hreflang="fr" href="http://www.forx.fr/">lien</a> et un autre <a href="http://forx.fr/">lien</a> puis un <a hreflang="fr" href="mailto:name@host.tld">email</a> et un autre <a href="mailto:name@host.tld">email</a> !donne :
Voici donc un [email=name@host.tld]email[/email] et un autre [email=name@host.tld]email[/email] !Hors ligne
en fait je viens de comprendre pourquoi en relisant mon message, c'est tout à fait normal car le premier passage pour les emails avec ce pattern :
<a.*?href="mailto:(.*?)">(.*?)</a>
au premier [c]<a[/c] (c'est à dire le premier lien) il déclenche puis va chercher à prendre tous les caractères jusqu'à ce qu'il trouve [c]href="mailto:[/c] donc tout ce qu'il y a entre est pris et supprimé, c'est à dire tout ceci dans mon exemple : [c] hreflang="fr" href="http://www.forx.fr/">lien</a> et un autre <a href="http://forx.fr/">lien</a> puis un <a hreflang="fr" [/c]
Hors ligne
Ah, excuse. J'ai cru comprendre ton problème maintenant :
tu voudrais pouvoir mettre des attributs à gauche ET à droite de "href" ?
mais pour les liens c'est plus compliqué car il peut y avoir d'autres attributs de chaques côtés de l'attribut href
Ben c'est assez simple :
'#<a.*?href="(.*?)">(.*?)</a>#s' // avant
'#<a.*?href="(.*?)".*?>(.*?)</a>#s' // après
Dernière modification par nicolas2k10 (26-08-2006 01:47:27)
Hors ligne
relis mon message juste avant, ce genre de pattern va fonctionner pour un élément sorti du contexte de la chaine de caractère mais si il y a plusieurs liens/emails dans la chaine cela ne va pas fonctionner
en fait je pense qu'il faut que je traite les éléments de la chaine un par un à l'aide d'une première fonction
Hors ligne
Oui, j'ai bien compris le problème maintenant (en testant en localhost, je vois bien le pb). Je regarde à ça et te préviens dès que j'ai trouvé. 
EDIT: Arfff... J'y suis presque ! 
Dernière modification par nicolas2k10 (26-08-2006 02:00:54)
Hors ligne
lol moi aussi mais il me prend encore pas en compte les liens 
Hors ligne
J'ai réussi !!!!! 
-Rectification... petit problème mais minime, je règle ça hillico 
Dernière modification par nicolas2k10 (26-08-2006 22:34:44)
Hors ligne
\o\O/o/
je sais pas ce que c'est que le petit problème mais je le vois pas ! en tout cas c'est tout de suite bcp mieux 
bon aller au lit j'vais pouvoir dormir tranquile 
merci !!
Hors ligne
Héhé moi je continue grrr, je veux trouver ! 
J'ai compris en plus et j'y suis presque donc...
Bonne nuit 
En principe, tu auras ça correctement fait pour demain matin. 
Hors ligne
ok c'est cool, bon courage alors 
la fonction actuelle avant d'aller au lit :
/**
* EXPERIMENTAL
*
* @function simpleXhtml2bbcode
*
* Transforme les balises XHTML en BBcode
*
* Merci à Nicolas (nicolas2k10 sur punbb.fr)
* pour les regex des liens.
*
* @param string str Chaîne à convertir
* @return string
*/
function simpleXhtml2Bbcode($str)
{
$pattern = array(
'#<span\s*style="color:\s*([a-zA-Z]*|\#?[0-9a-fA-F]{6})\s*;?\s*">(.*?)</span>#s',
'#<a(?:[^href=]|\s)*?href="mailto:(.*?)".*?>(.*?)</a>#s',
'#<a.*?href="(.*?)".*?>(.*?)</a>#s',
'#<img.*?src="(.*?)".*?/>#s',
'#<strong.*?>(.*?)</strong>#s',
'#<em.*?>(.*?)</em>#s',
'#<blockquote.*?>(.*?)</blockquote>#s',
'#<li.*?>(.*?)</li>#s',
'#<p.*?>(.*?)</p>#s'
);
$replace = array(
'[color=$1]$2[/color]',
'[email=$1]$2[/email]',
'[url=$1]$2[/url]',
'[img]$1[/img]',
'[b]$1[/b]',
'[i]$1[/i]',
'[quote]$1[/quote]
',
"* $1",
"$1\n\n"
);
$str = preg_replace($pattern, $replace, $str);
$pattern = array('<br />', ' ', ' ', ' ');
$replace = array("\n", "\t", ' ', ' ');
$str = str_replace($pattern, $replace, $str);
return strip_tags($str);
}Hors ligne
Héhé, thanks pour le chtit commentaire en plus.
;)
~6h30 du matin... mais j'y suis arrivé ! Par contre, je n'expliquerais pas comment en détail maintenant vu l'heure looool ! 
Avec ceci, tu peux avoir n'importe quels attributs AVANT et/ou APRES ! 
'Tin, j'en ai chié lol ! Une nuit ! 
Pattern :
'#<a(?:\s|\w*="[^"]*")*href="(?=mailto)mailto:([^"]+)"[^>]*>(.*)</a>#U',
'#<a(?:\s|\w*="[^"]*")*href="(?!mailto)([^"]+)"[^>]*>(.*)</a>#U',Replace :
'[email=$1]$2[/email]', // liens e-mail
'[url=$1]$2[/url]', // liensTest (tout réuni
) :
$string = 'Voici donc un <a class="c1" hreflang="fr" href="http://www.lien1.fr/" onclick="alert(\'test avec javascript\');" style="color: red;">lien (1)</a> et un autre <a href="http://lien2.fr">lien (2)</a> puis un <a href="mailto:name1@host.tld">email (1)</a> et un autre <a id="id2" hreflang="fr" href="mailto:name2@host.tld" style="color: green;">email (2)</a> puis un <a class="c3" href="http://www.lien3.fr" style="text-decoration: none;">lien (3)</a> !';
echo '<h1>Avant</h1>'.$string;
echo '<h1>Après</h1>'.simpleXhtml2bbcode($string);N'empêche ça tombe bien, les regex c'est mon kiff du moment et ici, j'ai beaucoup appris en cherchant dans les manuels (utilisation des assertions arrières/avants, etc.). 
PS : Pour info, ?: permet, du fait qu'il ne met pas en variable le contenu, d'améliorer la rapidité du traitement. Donc à utiliser souvent lorsque l'on utilise les parenthèses comme délimiteur seulement. 
PPS : Résultat du timing sur le test en ligne du site Lumadis :
Résultats Timing sur 200 itérations (sur le contenu de $string = 5 liens)
Durée: 0.0056190490722656 sec.Résultats Timing sur 200 itérations (sur le contenu de $string x4 = 20 liens)
Durée: 0.010270118713379 sec.

Dernière modification par nicolas2k10 (26-08-2006 07:23:17)
Hors ligne
je vois qu'on s'amuse bien ici héhé
mais dis moi vin100... cette p'tite fonction... elle ne servirait à lier PunBB et DC?
:canon:
Hors ligne
~6h30 du matin... mais j'y suis arrivé ! Par contre, je n'expliquerais pas comment en détail maintenant vu l'heure looool !
Avec ceci, tu peux avoir n'importe quels attributs AVANT et/ou APRES !
'Tin, j'en ai chié lol ! Une nuit !
mais il est fou ! 
merci bcp 
Je regarde à ton code et je vois ceci : [^>] ; je pense que je vais pouvoir avantageusement remplacer mes [c]<tag.*?>(.*?)</tag>[/c] par [c]<tag[^>]*>(.*?)</tag>[/c] ; si je comprend déduis bien cela veut dire tous les caractères sauf >
donc ça s'arrête quand il rencontre le chevron fermant, impécable.
Du coup j'ai aussi essayé de modifier pour l'élément <img>, mais là je ne suis pas sûr de ce que j'ai fait, si tu peut regarder.
Bref, au final ça donne maintenant ça :
/**
* @function simpleXhtml2bbcode
*
* Transforme les balises XHTML en BBcode
*
* Merci à Nicolas (nicolas2k10 sur punbb.fr)
* pour les regex des liens.
*
* @param string str Chaîne à convertir
* @return string
*/
function simpleXhtml2Bbcode($str)
{
$pattern = array(
'#<span\s*style="\s*color:\s*([a-zA-Z]*|\#?[0-9a-fA-F]{6})\s*;?\s*">(.*?)</span>#s',
'#<a(?:\s|\w*="[^"]*")*href="(?=mailto)mailto:([^"]+)"[^>]*>(.*)</a>#U',
'#<a(?:\s|\w*="[^"]*")*href="(?!mailto)([^"]+)"[^>]*>(.*)</a>#U',
'#<img(?:\s|\w*="[^"]*")*src="(.*?)"[^/]*/>#s',
'#<strong[^>]*>(.*?)</strong>#s',
'#<em[^>]*>(.*?)</em>#s',
'#<blockquote[^>]*>(.*?)</blockquote>#s',
'#<li[^>]*>(.*?)</li>#s',
'#<p[^>]*>(.*?)</p>#s'
);
$replace = array(
'[color=$1]$2[/color]',
'[email=$1]$2[/email]',
'[url=$1]$2[/url]',
'[img]$1[/img]',
'[b]$1[/b]',
'[i]$1[/i]',
'[quote]$1[/quote]
',
"* $1",
"$1\n\n"
);
$str = preg_replace($pattern, $replace, $str);
$pattern = array('<br />', ' ', ' ', ' ');
$replace = array("\n", "\t", ' ', ' ');
$str = str_replace($pattern, $replace, $str);
return strip_tags($str);
}Hors ligne
je vois qu'on s'amuse bien ici héhé
![]()
mais dis moi vin100... cette p'tite fonction... elle ne servirait à lier PunBB et DC?
![]()
:canon:
ça pourrait, mais c'est pour puntal... pour le moment, mais ça pourra aussi effectivement servir dans pleins d'autres projets liés à punbb 
Hors ligne
'#<img(?:\s|\w*="[^"]*")*src="(.*)"[^/]*/>#Us',Tu y étais presque mais ton raisonnement était bon en tout cas. 
Tu avais juste oublié l'option U à la fin (permet de ne pas devoir mettre ? à côté de chaque * ou +) (mode non-gourmand) et mis justement un ? de trop. 
Ou pouvait aussi mettre ? à chaque fois et virer l'option U.
Pour info,
<a href="[^"]*">sera plus rapide que ceci :
<a href=".*">Dernière modification par nicolas2k10 (26-08-2006 10:26:19)
Hors ligne
ok donc si je comprend bien pour tous les tags plutôt que de faire :
<tag[^>]*>(.*?)</tag>on peut avantageusement faire :
<tag[^>]*>([^<]*)</tag>non ?
Hors ligne
j'me répond tout seul : ah non je dis une connerie, pour une raison ou une autre il peut y avoir des chevrons (même si c'est pas XHTML compliant) uen personnes inexpérimenté peut le faire donc non
Hors ligne