it-roy-ru.com

регулярное выражение для извлечения текста из HTML

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

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

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

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

14
Ron Harlev

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

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


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

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

11
S.Lott

Удалить JavaScript и CSS:

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

Удалить теги

<.*?>
14
nickf

Требуется решение регулярных выражений (в 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 раз быстрее!

6
Joe Bergevin

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

 // тело // текст () [нет (предок :: сценарий)] [нет (предок :: стиль)] 
4
Chris Noe

Самый простой способ для простого 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'
2
David Avsajanishvili

Вот функция для удаления даже самых сложных 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
Ayush

Разве вы не можете просто использовать элемент управления 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
Shiroy

Используя синтаксис Perl для определения регулярных выражений, можно начать с:

!<body.*?>(.*)</body>!smi

Затем примените следующую замену к результату этой группы:

!<script.*?</script>!!smi
!<[^>]+/[ \t]*>!!smi
!</?([a-z]+).*?>!!smi
/<!--.*?-->//smi

Это, конечно, не отформатирует вещи в виде текстового файла, но удалит весь HTML (в основном, есть несколько случаев, когда он может работать не совсем правильно). Тем не менее, лучше использовать синтаксический анализатор XML на любом языке, который вы используете, чтобы правильно проанализировать HTML и извлечь из него текст.

1
Matthew Scharley

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

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

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

1
Robert Elwell

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

1
unigogo
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
mahesh

Я верю, что ты можешь просто сделать

document.body.innerText

Который будет возвращать содержимое всех текстовых узлов в документе, видимых или нет.

[edit (olliej): вздох неважно, это работает только в Safari и IE, и я не могу быть обеспокоен загрузкой Firefox по ночам, чтобы увидеть, существует ли он в транке: - /]

0
olliej