Разделите якоря до их содержимого, только если URL-адрес якоря содержит

Кто-нибудь знает функцию регулярного выражения в PHP для удаления содержимого привязки, только если атрибут href привязки содержит определенный текст?

Например, у меня есть HTML-страница, и повсюду есть ссылки. Но я хочу удалить только те привязки, которые содержат «yahoo» в URL-адресе. Таким образом, <a href="http://pages.yahoo.com/page1">Example page</a> станет: Example, в то время как другие якоря в 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
Клетус, спасибо, но я все еще не думаю, что ты правильно читаешь задачу. Я хотел бы удалить только теги и оставить содержимое привязки, только если 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