регулярное выражение для извлечения текста из HTML - PullRequest
15 голосов
/ 08 октября 2008

Я хотел бы извлечь из общей HTML-страницы весь текст (отображается или нет).

Я бы хотел удалить

  • любые теги HTML
  • Любой JavaScript
  • Любые стили CSS

Есть ли регулярное выражение (одно или несколько), которое достигнет этого?

Ответы [ 12 ]

15 голосов
/ 08 октября 2008

Удалить JavaScript и CSS:

<(script|style).*?</\1>

Удалить теги

<.*?>
11 голосов
/ 08 октября 2008

Вы не можете реально анализировать HTML с помощью регулярных выражений. Это слишком сложно. RE не будет правильно обрабатывать <![CDATA[ разделы. Кроме того, некоторые виды обычных HTML-вещей, таких как &lt;text>, будут работать в браузере как правильный текст, но могут сбить с толку наивное RE.

Вы будете счастливее и успешнее с правильным HTML-парсером. Люди Python часто используют что-то Beautiful Soup для анализа HTML и удаления тегов и сценариев.


Кроме того, браузеры по своему дизайну допускают некорректный HTML. Таким образом, вы часто будете пытаться анализировать HTML, который явно некорректен, но в браузере работает нормально.

Возможно, вы сможете проанализировать плохой HTML с RE. Все это требует терпения и тяжелой работы. Но часто проще использовать чужой парсер.

6 голосов
/ 26 декабря 2012

Требуется решение регулярных выражений ( в php ), которое бы возвращало простой текст (или лучше, чем) PHPSimpleDOM, только намного быстрее. Вот решение, которое я придумал:

function plaintext($html)
{
    // remove comments and any content found in the the comment area (strip_tags only removes the actual tags).
    $plaintext = preg_replace('#<!--.*?-->#s', '', $html);

    // put a space between list items (strip_tags just removes the tags).
    $plaintext = preg_replace('#</li>#', ' </li>', $plaintext);

    // remove all script and style tags
    $plaintext = preg_replace('#<(script|style)\b[^>]*>(.*?)</(script|style)>#is', "", $plaintext);

    // remove br tags (missed by strip_tags)
    $plaintext = preg_replace("#<br[^>]*?>#", " ", $plaintext);

    // remove all remaining html
    $plaintext = strip_tags($plaintext);

    return $plaintext;
}

Когда я проверил это на некоторых сложных сайтах (форумы, кажется, содержат некоторые из более сложных HTML для анализа), этот метод дал тот же результат, что и открытый текст PHPSimpleDOM, только намного, намного быстрее. Он также правильно обрабатывал элементы списка (теги li), а PHPSimpleDOM - нет.

Что касается скорости:

  • SimpleDom: 0,03248 с.
  • RegEx: 0,00087 сек.

в 37 раз быстрее!

4 голосов
/ 08 октября 2008

Созерцание делать это с регулярными выражениями утомительно. Вы рассматривали XSLT? Выражение XPath для извлечения всех текстовых узлов в документе XHTML, за исключением содержимого сценария и стиля, будет:

//body//text()[not(ancestor::script)][not(ancestor::style)]
2 голосов
/ 09 января 2011

Вот функция для удаления даже самых сложных HTML-тегов.

function strip_html_tags( $text ) 
{

$text = preg_replace(
    array(
        // Remove invisible content
        '@<head[^>]*?>.*?</head>@siu',
        '@<style[^>]*?>.*?</style>@siu',
        '@<script[^>]*?.*?</script>@siu',
        '@<object[^>]*?.*?</object>@siu',
        '@<embed[^>]*?.*?</embed>@siu',
        '@<applet[^>]*?.*?</applet>@siu',
        '@<noframes[^>]*?.*?</noframes>@siu',
        '@<noscript[^>]*?.*?</noscript>@siu',
        '@<noembed[^>]*?.*?</noembed>@siu',

        // Add line breaks before & after blocks
        '@<((br)|(hr))@iu',
        '@</?((address)|(blockquote)|(center)|(del))@iu',
        '@</?((div)|(h[1-9])|(ins)|(isindex)|(p)|(pre))@iu',
        '@</?((dir)|(dl)|(dt)|(dd)|(li)|(menu)|(ol)|(ul))@iu',
        '@</?((table)|(th)|(td)|(caption))@iu',
        '@</?((form)|(button)|(fieldset)|(legend)|(input))@iu',
        '@</?((label)|(select)|(optgroup)|(option)|(textarea))@iu',
        '@</?((frameset)|(frame)|(iframe))@iu',
    ),
    array(
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
        "\n\$0", "\n\$0", "\n\$0", "\n\$0", "\n\$0", "\n\$0",
        "\n\$0", "\n\$0",
    ),
    $text );

// Remove all remaining tags and comments and return.
return strip_tags( $text );
    }
2 голосов
/ 21 апреля 2010

Самый простой способ для простого HTML (пример на Python):

text = "<p>This is my> <strong>example</strong>HTML,<br /> containing tags</p>"
import re
" ".join([t.strip() for t in re.findall(r"<[^>]+>|[^<]+",text) if not '<' in t])

Возвращает это:

'This is my> example HTML, containing tags'
1 голос
/ 03 февраля 2012
string decode = System.Web.HttpUtility.HtmlDecode(your_htmlfile.html);
                Regex objRegExp = new Regex("<(.|\n)+?>");
                string replace = objRegExp.Replace(g, "");
                replace = replace.Replace(k, string.Empty);
                replace.Trim("\t\r\n ".ToCharArray());

then take a label and do "label.text=replace;" see on label out put

.

1 голос
/ 01 октября 2011

Разве вы не можете просто использовать элемент управления WebBrowser, доступный в C #?

        System.Windows.Forms.WebBrowser wc = new System.Windows.Forms.WebBrowser();
        wc.DocumentText = "<html><body>blah blah<b>foo</b></body></html>";
        System.Windows.Forms.HtmlDocument h = wc.Document;
        Console.WriteLine(h.Body.InnerText);
1 голос
/ 01 февраля 2009

Не уверен, эта страница может помочь.

1 голос
/ 08 октября 2008

Если вы используете PHP, попробуйте Simple HTML DOM, доступную на SourceForge.

В противном случае, Google html2text, и вы найдете множество реализаций для разных языков, которые в основном используют серию регулярных выражений, чтобы высосать всю разметку. Будьте осторожны, потому что иногда можно оставить теги без окончаний, а также специальные символы, такие как & (который & & amp;).

Кроме того, следите за комментариями и Javascript, поскольку я обнаружил, что особенно раздражает работа с регулярными выражениями, и почему я обычно просто предпочитаю, чтобы бесплатный анализатор делал всю работу за меня.

...