Как я могу удалить весь тег HTML (и его содержимое) по его классу с помощью регулярных выражений? - PullRequest
7 голосов
/ 22 октября 2008

Я не очень хорош с Regex, но я учусь.

Я хотел бы удалить html-тег по имени класса. Это то, что я до сих пор:

<div class="footer".*?>(.*?)</div>

Первый. *? потому что он может содержать другой атрибут, а во-вторых, он может содержать другие HTML-материалы.

Что я делаю не так? Я пробовал много сет без успеха.

Обновление

Внутри DIV он может содержать несколько строк, и я играю с регулярным выражением Perl.

Ответы [ 8 ]

17 голосов
/ 22 октября 2008

Как уже говорили другие люди, HTML сложно использовать с регулярными выражениями, и подход DOM может быть лучше. E.g.:

use HTML::TreeBuilder::XPath;

my $tree = HTML::TreeBuilder::XPath->new;
$tree->parse_file( 'yourdocument.html' );

for my $node ( $tree->findnodes( '//*[@class="footer"]' ) ) {
    $node->replace_with_content;   # delete element, but not the children
}

print $tree->as_HTML;
14 голосов
/ 22 октября 2008

Вы также захотите учесть другие вещи перед занятием в теге div

<div[^>]*class="footer"[^>]*>(.*?)</div>

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

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

<div>
    <div class="footer">
        <div>Hi!</div>
    </div>
</div>

Попытка построить регулярное выражение для этого - путь к катастрофе. Лучше всего загрузить документ в DOM и выполнить с ним манипуляции.

Псевдокод, который должен быть тесно связан с XML :: DOM:

document = //load document
divs = document.getElementsByTagName("div");
for(div in divs) {
    if(div.getAttributes["class"] == "footer") {
        parent = div.getParent();
        for(child in div.getChildren()) {
            // filter attribute types?
            parent.insertBefore(div, child);
        }
        parent.removeChild(div);
    }
}


Вот библиотека Perl, HTML :: DOM , и другая, XML :: DOM
.NET имеет встроенные библиотеки для обработки dom-анализа.
1 голос
/ 05 февраля 2009
<div[^>]*class="footer"[^>]*>(.*?)</div>

Работало для меня, но нужно было использовать обратную косую черту перед специальными символами

<div[^>]*class=\"footer\"[^>]*>(.*?)<\/div>
1 голос
/ 22 октября 2008

В Perl вам нужен модификатор /s, иначе точка не будет соответствовать новой строке.

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

0 голосов
/ 22 октября 2008

Это будет сложно из-за жадности регулярных выражений (обратите внимание, что мои примеры могут быть специфичными для perl, но я знаю, что жадность - общая проблема с RE.) Второй .*? будет соответствовать максимально возможному количеству до </div>, поэтому, если у вас есть следующее:

<div class="SomethingElse"><div class="footer"> stuff </div></div>

Выражение будет соответствовать:

<div class="footer"> stuff </div></div>

что вряд ли то, что вы хотите.

0 голосов
/ 22 октября 2008

Попробуйте это:

<([^\s]+).*?class="footer".*?>([.\n]*?)</([^\s]+)>

Ваша самая большая проблема - это вложенные теги. Например:

<div class="footer"><b></b></div>

Данное регулярное выражение будет соответствовать всему через </b>, оставляя </div> в конце. Вам нужно будет либо предположить, что искомый тег не имеет вложенных элементов, либо вам придется использовать какой-то синтаксический анализатор из HTML в DOM и запрос XPath для удаления всего поддерева.

0 голосов
/ 22 октября 2008

почему бы и нет <div class="footer".*?</div> Я тоже не гуру регулярных выражений, но я не думаю, что вам нужно указывать эту последнюю скобку для вашего открытого тега div

0 голосов
/ 22 октября 2008

Частично зависит от того, какой именно движок регулярных выражений вы используете - какой язык и т. Д. Но одна возможность состоит в том, что вам нужно избегать кавычек и / или косой черты. Вы также можете сделать это без учета регистра.

<div class=\"footer\".*?>(.*?)<\/div>

В противном случае, скажите, пожалуйста, какой язык / платформу вы используете - .NET, java, perl ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...