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 13/04/2007, 16h19   #1
Membre éclairé
 
Inscription : décembre 2004
Messages : 658
Détails du profil
Informations personnelles :
Âge : 29
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : décembre 2004
Messages : 658
Points : 317
Points : 317
Par défaut Supprimer doublons et garder valeur

Bonjour

j'ai un code html généré qui donne ca
Code :
1
2
 
<span style="color:green;"><span style="font-size:14px;">
Et je voudrais remplacer ce texte par :
Code :
1
2
 
<span style="color:green;font-size:14px;">
pour ceci j'utilise preg_replace avec une fonction que j'ai crée mais ca fonctionne pas vraiment enfin pas du tout

mon code :
Code :
1
2
 
preg_replace('#(<span style="(.+?)">){1}(<span style="(.+?)">){1}#si','<span style="$1 $2">',$texte);
Quelqu'un pourrait il maider à voir mon erreur merci.

EDIT : j'ai oublié de préciser, ici je met deux span d'affilé mais ca peut etre 5 comme dix je connais pas le nombre exacte.

J'ai reussi avec le code suivant à le faire fonctionner pour 2 span mais pas pour plus.
Code :
1
2
 
preg_replace('#<span style="(.+?)"><span style="(.+?)">#si','<span style="$1 $2">',$texte);
zulot est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/04/2007, 00h38   #2
Membre habitué
 
Avatar de daniel61
 
Inscription : décembre 2006
Messages : 109
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 109
Points : 120
Points : 120
un remplacement délicat peut être fait par preg_replace_callback() où il est possible de faire un sous traitement en php comme regex.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
function span_replace($span) {
  if(preg_match_all('#style=["\'](.+?)["\']#',$span[0],$style)) {
    return '<span style="'.implode('',$style[1]).'">';
  }
  return $span[0];
}
 
$html='
<span style="color:green;">
<span style="font-size:14px;">
<span style="background:yellow;">
<span style="font-weight:bold;">
';
 
$test=preg_replace_callback('#(?:<span style=["\'].+?["\']>\s*)+#','span_replace',$html);
echo htmlentities($test);
quant preg_replace_callback() rencontrera une séquence de <span style="...">, alors la fonction span_replace sera appellée pour joindre les styles en un seul span grâce à preg_match_all().

même si j'ai testé le code qui précède, je pense que tu as oublié de dire ce que tu veux faire des </span> et des autres attributs des span... s'il y a d'autres attributs, mais l'idée est là avec preg_replace_callback().
daniel61 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/04/2007, 09h55   #3
Membre éclairé
 
Inscription : décembre 2004
Messages : 658
Détails du profil
Informations personnelles :
Âge : 29
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : décembre 2004
Messages : 658
Points : 317
Points : 317
En fait les </span> je les ai deja traité.

Et comme ce code vient d'une mise en page d'un editeur je suis sur qu'il n'y aura a chaque fois qu'une seul attribut par span.

Merci je vais tester ton code.


EDIT: ca fonctionne nickel merci

EDIT2 : Tu peux m'expliquer cette expression reguliere je la comprend pas tres bien :
Code :
#(?:<span style=["\'].+?["\']>\s*)+#
zulot est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/04/2007, 17h45   #4
Membre habitué
 
Avatar de daniel61
 
Inscription : décembre 2006
Messages : 109
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 109
Points : 120
Points : 120
salut

le point d'interrogation peut représenter 3 fonctions distinctes. il peut être un facteur de répétition pour dire 0 ou 1 fois, il n'est pas utiliser comme ça ici. par contre il est utiliser dans ses 2 autres formes.

si le point d'interrogation est après une ouverture de parenthèse alors il indique que le caractère suivant sera une fonction à appliquer sur la parenthèse entière. (?:...) veut simplement dire de désactiver la possibilté de capture qui aurait été en \\1. la parenthèse (masque) est donc seulement utilisé comme regroupement de pattern, et le "+" suivant le masque veut dire de répéter 1 ou plusieurs fois le pattern complet. donc de prendre tous les <span...> consécutifs, par défaut il y a une capture en \\0 de la sous-chaine qui a satisfait l'expression entière, c'est seulement cette capture en \\0 que nous avons besoin. tu l'auras compris, ?: n'est pas obligatoire mais c'est une bonne habitude parcequ'il permet de prendre moins de mémoire, donc comme on a seulement besoin de \\0 et d'un regroupement pour pouvoir répéter le masque, j'ai utilisé ?: pour désactivé \\1 dans le tableau de résultats, ce qui n'est pas à négliger sur de grande quantité de données.

lorsque le point d'interrogation est utilisé après un caractère de répétition, alors il permet de changer l'état greedy/ungreedy, par défaut c'est greedy (glouton) ici ["\'].+?["\'] veut dire de rechercher la séquence de 1 ou plusieurs caractères entre ' ou " en mode ungreedy (non glouton), donc dès qu'il rencontrera le premier caractère ' ou " il arrêtera, alors que greedy lui tenterait de rechercher le caractère ' ou " le plus loin possible.

finalement, dans les autres contextes, le point d'interrogation veut dire de répéter 0 ou 1 fois... tu peux retrouver une expression qui pourrait utiliser le point d'interrogation dans ses 3 formes... (?:ba??)? voudrait dire de répéter le caractère "a" 0 ou 1 fois en mode ungreedy qui est précéder du caractère "b", de regrouper ce pattern en un masque non capturant et de répéter ce masque complet 0 ou 1 fois... pas très logique comme expression, m'enfin.

il reste peut être à parler de \s*, \s est une classe de caractère qui représente les caractères blancs, qui sont 9-tab, 10-line feed/new line, 12-form feed, 13-carriage return et bien entendu 32-espace. "*" est le caractère de répétition pour 0 ou plusieurs fois. donc <span...><span...> est accepter, <span...> <span...> est accepter, les <span...> séparer par des retour à ligne sont aussi acceptés, et ainsi de suite.

(?: masque de regroupement sans capture
<span style= le pattern du masque commence par <span style=
["\'].+?["\'] puis tout caractère entre " ou ' et arrêter dès qu'un de ces 2 caractères est rencontré
>\s* puis suivit de > et toute séquence de 0 ou plusieurs blancs
) fin du masque
+ et répéter le pattern dans le masque 1 ou plusieurs fois

plusieurs fois peut être vu comme l'infini et je commencais à croire que j'allais écrire à l'infini aussi désolé si j'ai parlé de choses que tu connaissais déjà.

par contre, je vois que j'ai oublié le cas de "background:url('aaa.jpg');" le code modifié est
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
function span_replace($span) {
  if(preg_match_all('#style=(["\'])(.+?)\1#',$span[0],$style)) {
    return '<span style="'.implode('',$style[2]).'">';
  }
  return $span[0];
}
 
$html=<<<test
<span style="color:green;">
<span style="font-size:14px;">
<span style="background:yellow;">
<span style="background:url('test.jpg');">
<span style="font-weight:bold;">
test;
 
$test=preg_replace_callback('#(?:<span style=(["\']).+?\1>\s*)+#','span_replace',$html);
echo htmlentities($test);
bon... \1 est très simple, il réfère à la capture déjà fait en \\1, première parenthèse capturante, comme ça il pourrait y avoir des ' dans les " et inversement. désolé pour l'oubli
daniel61 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 13h35.


 
 
 
 
Partenaires

Hébergement Web