preg_replace需要表达式的帮助

时间:2011-08-31 08:26:50

标签: php regex preg-replace

这是我的代码:

$string = '<a href="http://www.mysite.com/test" class="prevlink">&laquo; Previous</a><a href=\'http://www.mysite.com/test/\' class=\'page\'>1</a><span class=\'current\'>2</span><a href=\'http://www.mysite.com/test/page/3/\' class=\'page\'>3</a><a href=\'http://www.mysite.com/test/page/4/\' class=\'page\'>4</a><a href="http://www.mysite.com/test/page/3/" class="nextlink">Next &raquo;</a>';
$string = htmlspecialchars($string, ENT_COMPAT, 'UTF-8');
$string = preg_replace('@(&lt;a).*?(nextlink)@s', '', $string);
    echo $string;

我正在尝试删除最后一个链接:

<a href="http://www.mysite.com/test/page/3/" class="nextlink">Next &raquo;</a>';

我目前的输出:

">Next &raquo;</a>

它从一开始就删除了所有内容。 我希望它只删除带有strpos的那个,这是否可以使用preg_replace以及如何实现? 感谢。

2 个答案:

答案 0 :(得分:1)

注意:这不是直接的答案,而是对另一种方法的建议。

有人告诉我一次;如果你能以任何其他方式做到这一点,请远离正则表达式。我不喜欢,这是我的白鲸。你听说过phpQuery吗?它是用PHP实现的jQuery,功能非常强大。它能够以一种非常简单的方式做你想做的事。我知道这不是正则表达式,但也许对你有用。

如果你真的想继续,我可以推荐http://gskinner.com/RegExr/。我认为这是一个很棒的工具。

答案 1 :(得分:1)

要解决的问题非常棘手

首先, 。*?不会像你期望的那样匹配。

它从左边开始找到&lt; a的第一个匹配,然后搜索直到找到nextlink,这实际上是拾取整个字符串。

要使正则表达式按照您的意愿工作,首先需要从右侧进行匹配,然后通过字符串向后工作,找到最小(非贪婪)匹配

我看不到任何可以做到这一点的修饰符 所以我选择在每个链接上进行回调,这将检查并删除其中包含nextlink的任何链接

<?php
$string = '<a href="http://www.mysite.com/test" class="prevlink">&laquo; Previous</a><a href=\'http://www.mysite.com/test/\' class=\'page\'>1</a><span class=\'current\'>2</span><a href=\'http://www.mysite.com/test/page/3/\' class=\'page\'>3</a><a href=\'http://www.mysite.com/test/page/4/\' class=\'page\'>4</a><a href="http://www.mysite.com/test/page/3/" class="nextlink">Next &raquo;</a>';

echo "RAW: $string\r\n\r\n";

$string = htmlspecialchars($string, ENT_COMPAT, 'UTF-8');

echo "SRC: $string\r\n\r\n";


    $string = preg_replace_callback(
        '@&lt\;a.+?&lt;/a&gt;@',
        'remove_nextlink',
        $string
    );


function remove_nextlink($matches) {

    // if you want to see each line as it works, uncomment this
    // echo "L: $matches[0]\r\n\r\n";

    if (strpos($matches[0], 'nextlink') === FALSE) {
        return $matches[0]; // doesn't contain nextlink, put original string back
    } else {
        return ''; // contains nextlink, replace with blank
    }
}    

echo "PROCESSED: $string\r\n\r\n";