php
  • regex
  • 2010-05-05 4 views 3 likes 
    3

    мне нужно преобразоватьИспользование регулярных выражений для удаления HTML-теги

    $text = 'We had <i>fun</i>. Look at <a href="http://example.com">this photo</a> of Joe'; 
    

    [Изменить] Там может быть несколько ссылок в тексте.

    в

    $text = 'We had fun. Look at this photo (http://example.com) of Joe'; 
    

    Все HTML-теги должны быть удалены и HREF значение из <a> тегов должна быть добавлена, как и выше.

    Что было бы эффективным способом решить это с помощью регулярного выражения? Любой фрагмент кода был бы замечательным.

    +1

    'etc' – kennytm

    +0

    Вы не хотите решать это с помощью регулярного выражения. Используйте DOM, если вы заботитесь о своем здравомыслии. – Gordon

    +0

    Я не знаю, Гордон. Я извлек url ​​с помощью регулярного выражения намного проще, чем возиться с DOM. – Timothy

    ответ

    5

    Во-первых сделать preg_replace сохранить ссылку. Вы можете использовать:

    preg_replace('<a href="(.*?)">(.*?)</a>', '$\2 ($\1)', $str); 
    

    Затем используйте strip_tags, который будет прикончить остальных тегов.

    +0

    Это не сработает, так как здесь подробно объяснено, что html слишком сложный для анализа с использованием регулярного выражения. Например, этот простой будет разбиваться при использовании одинарных кавычек вместо удвоений в атрибуте href (чтобы исправить это, измените первую двойную кавычку с помощью: ([\ '\ "]), а вторая с обратной ссылкой) –

    +3

    Я согласен . (X) HTML - это _complex_, и нужно подумать дважды, прежде чем разбирать его с помощью регулярного выражения. Тем не менее, для быстрого однократного DOM может быть излишним. – nc3b

    +0

    @Lost_in_code Это не удастся, если пользователь добавит какой-либо другой атрибут в ссылку , например ' Gordon

    1

    попробуйте XML-парсер, чтобы заменить любой тег его внутренним html и тегами с его атрибутом href.

    http://www.php.net/manual/en/book.domxml.php

    0

    Я сделал такие вещи, используя вариации подстроки и заменив их. я бы, вероятно, использовать регулярное выражение сегодня но вы хотите альтернативу так:

    Для <i> тегов, я бы что-то вроде:

    $text = replace($text, "<i>", ""); 
    $text = replace($text, "</i>", ""); 
    

    (Мой PHP действительно ржавый, так replace не может быть правильным именем функции, но идея заключается в том, что я делюсь.)

    Тег <a> немного сложнее. Но это может быть сделано. Вам нужно найти, что начинается <a и заканчивается >. Затем извлечь всю длину и заменить закрытие </a>

    Это может пойти что-то вроде:

    $start = strrpos($text, "<a"); 
    $end = strrpos($text, "</a>", $start); 
    $text = substr($text, $start, $end); 
    $text = replace($text, "</a>", ""); 
    

    (я не знаю, если это будет работать, опять же идея, что я хочу общаться Я надеюсь, что фрагменты кода помогут, но они, вероятно, не работают «из коробки».Есть также много возможных ошибок в фрагментах кода в зависимости от конкретной реализации и окружающей среды)

    Ссылка:

    +0

    Спасибо за это, но я отредактировал вопрос, так как regex кажется быть способ пойти. Это намного проще и быстро. – Yeti

    1

    Решение DOM:

    $dom = new DOMDocument; 
    $dom->loadHTML($html); 
    $xpath = new DOMXPath($dom); 
    foreach($xpath->query('//a[@href]') as $node) { 
        $textNode = new DOMText(sprintf('%s (%s)', 
         $node->nodeValue, $node->getAttribute('href'))); 
        $node->parentNode->replaceChild($textNode, $node); 
    } 
    echo strip_tags($dom->saveHTML()); 
    

    и то же без XPath:

    $dom = new DOMDocument; 
    $dom->loadHTML($html); 
    foreach($dom->getElementsByTagName('a') as $node) { 
        if($node->hasAttribute('href')) { 
         $textNode = new DOMText(sprintf('%s (%s)', 
          $node->nodeValue, $node->getAttribute('href'))); 
         $node->parentNode->replaceChild($textNode, $node); 
        } 
    } 
    echo strip_tags($dom->saveHTML()); 
    

    Все это делает загружать любой HTML в DomDocument инстанции. В первом случае он использует выражение XPath, которое подобно SQL для XML, и получает все ссылки с атрибутом href. Затем он создает элемент текстового узла из innerHTML и атрибута href и заменяет ссылку. Вторая версия просто использует API DOM и Xpath.

    Да, это несколько строк больше, чем Regex, но это чисто и легко понять, и это не даст вам головных болей, когда вам нужно добавить дополнительную логику.

    0

    Это очень легко сделать с помощью парсера:

    # available from http://simplehtmldom.sourceforge.net 
    include('simple_html_dom.php'); 
    
    # parse and echo 
    $html = str_get_html('We had <i>fun</i>. Look at <a href="http://example.com">this photo</a> of Joe'); 
    
    $a = $html->find('a'); 
    $a[0]->outertext = "{$a[0]->innertext} ({$a[0]->href})"; 
    
    echo strip_tags($html); 
    

    И что производит код, который вы хотите в вашем тесте.

    Смежные вопросы