Отстранете котвите до тяхното съдържание, само ако URL адресът на котвата съдържа

Някой знае ли функция за регулярен израз в PHP, за да премахне съдържанието на котва, само ако атрибутът href на котвата съдържа конкретен текст?

Например, имам HTML страница и навсякъде има връзки. Но искам да премахна само котвите, които съдържат „yahoo“ в URL адреса. Така <a href="http://pages.yahoo.com/page1">Example page</a> ще стане: Пример, докато други котви в HTML, които не съдържат "yahoo", ще останат сами.


person Tony    schedule 12.03.2010    source източник
comment
Съжалявам, Тони, какво ще стане?   -  person zellio    schedule 12.03.2010


Отговори (2)


Първо, това не е проблем с регулярен израз (или поне не би трябвало да бъде). PHP идва с HTML анализатор, така че бих силно препоръчал да го използвате.

Когато използвате това, просто трябва да преминете през всички котви тагове, да проверите атрибута href и да го промените, ако е необходимо, след което да го запишете обратно в HTML. Например:

$dom = new DOMDocument;
$dom->loadHTML($html); // $html as a string
$anchors = $dom->getElementsByTagName('a');
for ($i=0; i<$anchors->length; $i++) {
  $item = $anchors->item[$i];
  $href = $item->getAttribute('href');
  $host = parse_url($href, PHP_URL_HOST);
  if (stripos($host, 'yahoo') !== false) {
    $item->parentNode->removeChild($item);
  }
}
$html = $dom->saveHTML();

Използването на parse_url() тук не е задължително. Можете просто да проверите дали стойността на атрибута има "yahoo" някъде в него, без да изваждате само името на хоста.

Това е значително по-добро и по-стабилно от всяко базирано на регулярен израз решение за същия проблем.

person cletus    schedule 12.03.2010
comment
-1|Ако щеше да промени файловете за постоянно, щеше да е по-добре да използва мощен редактор, за да свърши работата. - person aefxx; 12.03.2010
comment
Добре, решението ви изглежда страхотно, но още 2 въпроса. Що се отнася до производителността и използването на паметта, колко ефективно би било това в сравнение с решение с регулярен израз? Изглежда, че ще има много повече режийни разходи за тази опция. Също така, все още не съм тествал това, но изглежда, че във вашия пример просто модифицирате атрибута href на котвата, а не премахвате етикетите на котвата. Все още не знам какъв би бил регулярният израз за това, но мисля, че preg_replace ще свърши работа. - person Tony; 12.03.2010
comment
@Tony, ако правите това като част от изобразяването на страница, тогава латентността на мрежата вероятно ще бъде много по-голяма фабрика, освен ако не правите това на изключително голям документ. Използването на паметта е основно линейна функция от размера на документа, както и времето за обработка, така че това се мащабира добре. Регулярните изрази могат да бъдат по-непредвидими, ако попаднете в сценарии с прекомерно обратно проследяване. - person cletus; 13.03.2010
comment
@Tony също се промени, за да премахне елемента. - person cletus; 13.03.2010
comment
Благодаря, cletus, но все още не мисля, че четете проблема правилно. Бих искал да премахна само етикетите и да оставя съдържанието на котвата да остане, само ако href съдържа yahoo. Ето още един пример: <a href="http://books.yahoo.com">This Text</a> -› Този текст - person Tony; 13.03.2010

Опитайте тази функция.

public function stripAnchorTags($html, $ignore_host = false, $charset="UTF-8"){
        $dom = new DOMDocument;
        $dom->loadHTML('<?xml version="1.0" encoding="'.$charset.'"?>'.$html); // $html as a string
        $anchors = $dom->getElementsByTagName('a');
        $length = $anchors->length;
        for($i=0; $i<$length; $i++){
            $item = $anchors->item(0);
            $href = $item->getAttribute('href');
            $host = parse_url($href, PHP_URL_HOST);
            if(!$ignore_host || stripos($host, $ignore_host) === false) {
                $item->parentNode->replaceChild($dom->createTextNode($href),$item);
            }
        }
        return preg_replace('/^<!DOCTYPE.+?>/', '', str_replace( array('<html>', '</html>', '<body>', '</body>'), array('', '', '', ''), $dom->saveXML($dom->documentElement)));
    }

Можете да го използвате като този stripAnchorTags($html);

Ако искате да игнорира yahoo връзки, тогава го наречете така stripAnchorTags($html, "yahoo");

person Andrew Winter    schedule 08.09.2010