如何使用preg_replace枚举项目?

时间:2010-12-01 12:08:08

标签: php preg-replace enumerate

我需要在文档上的图像之前和之后添加一些标记,并立即对它们进行计算。 HTML文档代码是:

...

<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> 

我需要像这样的结果代码

<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> 

3 个答案:

答案 0 :(得分:1)

通常,您也可以使用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();
}

答案 1 :(得分:0)

我不是正则表达式+ HTML的粉丝,但是这里(我只是制作了一个简单的正则表达式 - 你可能已经有了一个):

$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);

Demo

重要的部分是e中的preg_replace()修饰符。请参阅“Example #4 Using the 'e' modifier。”


修改
正如评论中指出的那样,$i肯定不是全局变量的最佳名称。如果这将被用作简单的“一次性”转换,它可能没问题。如果没有,请将名称更改为冲突的内容。或者将其作为public static添加到班级中。

此外,preg_replace_callback()存在。它更适合,虽然我发现将函数名称作为字符串传递并且评估functionName('arg')几乎同样丑陋:)

答案 2 :(得分:0)

首先,您不应该使用Regexes来处理HTML。

然而,在这种情况下,你很容易处理全线:

$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;

输出:

<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>

当然,如果您打算再次使用回调,则需要将$last_num设置为0。 没有全局或静态变量,就没有办法做到这一点。但是,如果您只打算使用一次回调,只需将global $last_num;更改为static $last_num = 0;即可。然后它将永远增加,没有机会重置它 - 但它不会混乱你的全局命名空间。