2010-12-01 17 views
0

J'ai besoin d'ajouter des balises avant et après les images sur le document et de les numériser à la fois. HTML Code de document est:comment énumérer des articles avec preg_replace?

....

<img src="http://img.example.com/img/mage1.jpg" alt="sometile"> <br> 
<img src="http://img.example.com/img/image72.jpg" alt="sometile"> <br> 
<img src="http://img.example.com/img/imagstr.jpg" alt="sometile"> <br> 
<img src="http://img.example.com/img/image.jpg" alt="sometile"> <br> 
<img src="http://img.example.com/img/imgger.gif" alt="sometile"> <br> 
<img src="http://img.example.com/img/somepic.png" alt="sometile"> <br> 

J'ai besoin dans le code de résultat comme celui-ci

<div><a name="#pic1"></a><img src="http://img.example.com/img/mage1.jpg" alt="sometile"></div> 
<div><a name="#pic2"></a><img src="http://img.example.com/img/image72.jpg" alt="sometile"> </div> 
<div><a name="#pic3"></a><img src="http://img.example.com/img/imagstr.jpg" alt="sometile"> </div> 
<div><a name="#pic4"></a><img src="http://img.example.com/img/image.jpg" alt="sometile"> </div> 
<div><a name="#pic5"></a><img src="http://img.example.com/img/imgger.gif" alt="sometile"> </div> 
<div><a name="#pic6"></a><img src="http://img.example.com/img/somepic.png" alt="sometile"> </div> 

Répondre

0

Je ne suis pas fan de regex + HTML, mais va ici (Je viens une regex cuisinais simple, — vous avez probablement déjà un):

$s = '<img src="http://img.example.com/img/mage1.jpg" alt="sometile"> <br> 
<img src="http://img.example.com/img/image72.jpg" alt="sometile"> <br> 
<img src="http://img.example.com/img/imagstr.jpg" alt="sometile"> <br> 
<img src="http://img.example.com/img/image.jpg" alt="sometile"> <br> 
<img src="http://img.example.com/img/imgger.gif" alt="sometile"> <br> 
<img src="http://img.example.com/img/somepic.png" alt="sometile"> <br>'; 

$i = 0; 
function wrap($s) { 
     global $i; 
     $i++; 
     return sprintf('<div><a name="pic%d">%s</div>', $i, $s); 
} 

print preg_replace('#(<img [^>]+?>) <br>#e', "wrap('\\1')", $s); 

(01 La partie importante est le modificateur e dans le preg_replace(). Voir "Example #4 Using the 'e' modifier".


EDIT
Comme indiqué dans les commentaires, $i est certainement pas le meilleur nom pour une variable globale. Si cela va être utilisé comme une simple transformation «ponctuelle», ça peut aller. Si ce n'est pas le cas, changez le nom en quelque chose qui sera non conflit. Ou mettez-le comme public static dans une classe.

Il existe également preg_replace_callback(). Il est mieux adapté, bien que je trouve le passage d'un nom de fonction comme une chaîne et l'évaluation functionName('arg') presque aussi moche :)

+1

'I' $ est certainement le pire nom que vous pouvez utiliser pour une variable globale. De plus, preg_replace_callback est votre ami - eval est diabolique. – ThiefMaster

+0

@ThiefMaster Re: '$ i' en effet :) Je ne connaissais pas' preg_replace_callback() '. – jensgram

+0

Greate solution I fonctionne parfaitement. Merci beaucoup – Java

0

Tout d'abord, vous n'êtes pas censé utiliser des expressions rationnelles pour faire face à HTML.

Cependant, dans ce cas, il est facile que vous êtes presque affaire avec des lignes complètes:

$code = '<img src="http://img.example.com/img/mage1.jpg" alt="sometile"> <br> 
<img src="http://img.example.com/img/image72.jpg" alt="sometile"> <br> 
<img src="http://img.example.com/img/imagstr.jpg" alt="sometile"> <br> 
<img src="http://img.example.com/img/image.jpg" alt="sometile"> <br> 
<img src="http://img.example.com/img/imgger.gif" alt="sometile"> <br> 
<img src="http://img.example.com/img/somepic.png" alt="sometile"> <br>'; 

function get_num_row($matches) { 
    global $last_num; 
    return '<div><a name="pic' . (++$last_num) . '">' . trim($matches[1]) . '</a></div>'; 
} 

$last_num = 0; 
$code = preg_replace_callback('/^(.*)<br>$/m', 'get_num_row', $code); 
echo $code; 

Sortie:

<div><a name="pic1"><img src="http://img.example.com/img/mage1.jpg" alt="sometile"></a></div> 
<div><a name="pic2"><img src="http://img.example.com/img/image72.jpg" alt="sometile"></a></div> 
<div><a name="pic3"><img src="http://img.example.com/img/imagstr.jpg" alt="sometile"></a></div> 
<div><a name="pic4"><img src="http://img.example.com/img/image.jpg" alt="sometile"></a></div> 
<div><a name="pic5"><img src="http://img.example.com/img/imgger.gif" alt="sometile"></a></div> 
<div><a name="pic6"><img src="http://img.example.com/img/somepic.png" alt="sometile"></a></div> 

Bien sûr, vous devez définir $last_num-0 si vous allez utilisez à nouveau le rappel. Il n'y a aucun moyen de le faire sans une variable globale ou statique. Mais si vous n'utilisez le rappel qu'une seule fois, vous pouvez simplement changer global $last_num; en static $last_num = 0;. Ensuite, il sera incrémenté pour toujours sans aucune chance de le réinitialiser - mais il n'encombrera pas votre espace de noms global.

+0

Merci pour la réponse fonctionne très bien. – Java

1

Comme d'habitude, vous pouvez aussi le faire avec DOM:

$counter = 0; 
$doc = new DOMDocument(); 
$doc->loadHTML($str); 
foreach ($doc->getElementsByTagName("img") as $img) { 
    $sibling = $img->nextSibling; 
    while ($sibling) { 
     if ($sibling instanceof DOMElement && $sibling->tagName === 'br') { 
      $sibling->parentNode->removeChild($sibling); 
     } 
     $sibling = $sibling->nextSibling; 
    } 
    $div = $doc->createElement("div"); 
    $img->parentNode->replaceChild($div, $img); 
    $a = $doc->createElement("a"); 
    $a->setAttribute("name", "pic" . (++$counter)); 
    $a->appendChild($img); 
    $div->appendChild($a); 
} 
$str = ''; 
foreach (simplexml_import_dom($doc->getElementsByTagName("body")->item(0))->children() as $elem) { 
    $str .= $elem->asXML(); 
} 
+0

Aussi bonne solution/J'ai utilisé la solution de jensgram c'est bon pour moi. – Java

+0

Merci beaucoup pour votre réponse. – Java