Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
895
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
914
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4351
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Мне нужно сопоставить и удалить все теги, используя регулярное выражение в Perl. У меня есть следующее:
<\\??(?!p).+?>
Но это все равно совпадает с закрывающим тегом </p> . Есть ли какие-либо подсказки о том, как соответствовать закрывающему тегу?
Обратите внимание, что это выполняется на xhtml.
Если вы настаиваете на использовании regex, что-то вроде этого будет работать в большинстве случаев:
# Remove all HTML except "p" tags
$html =~ s{<(?>/?)(?:[^pP]|[pP][^\s>/])[^>]*>}{}g;
Объяснение:
s{
< # opening angled bracket
(?>/?) # ratchet past optional /
(?:
[^pP] # non-p tag
| # ...or...
[pP][^\s>/] # longer tag that begins with p (e.g., <pre>)
)
[^>]* # everything until closing angled bracket
> # closing angled bracket
}{}gx; # replace with nothing, globally
Но на самом деле, избавьте себя от головной боли и используйте вместо этого парсер. CPAN имеет несколько подходящих модулей. Вот пример использования модуля HTML::TokeParser , который поставляется с чрезвычайно способным дистрибутивом HTML::Parser CPAN:
use strict;
use HTML::TokeParser;
my $parser = HTML::TokeParser->new('/some/file.html')
or die "Could not open /some/file.html - $!";
while(my $t = $parser->get_token)
{
# Skip start or end tags that are not "p" tags
next if(($t->[0] eq 'S' || $t->[0] eq 'E') && lc $t->[1] ne 'p');
# Print everything else normally (see HTML::TokeParser docs for explanation)
if($t->[0] eq 'T')
{
print $t->[1];
}
else
{
print $t->[-1];
}
}
HTML::Parser принимает входные данные в виде имени файла, дескриптора открытого файла или строки. Обернуть приведенный выше код в библиотеку и сделать адресат настраиваемым (т. е. не просто print ing, как в приведенном выше) не так уж сложно. Результат будет гораздо более надежным, ремонтопригодным и, возможно, также более быстрым (HTML::Parser использует серверную часть на основе C), чем попытка использовать регулярные выражения.
На мой взгляд, попытка разобрать HTML с помощью чего-либо другого, кроме парсера HTML, просто требует мира боли. HTML-это действительно сложный язык (что является одной из главных причин того, что был создан XHTML, который намного проще, чем HTML).
Например, это:
<HTML /
<HEAD /
<TITLE / > /
<P / >
является полным, 100% хорошо сформированным, 100% действительным HTML документом. (Ну, в нем отсутствует декларация DOCTYPE, но кроме этого ...)
Это семантически эквивалентно
<html>
<head>
<title>
>
</title>
</head>
<body>
<p>
>
</p>
</body>
</html>
Но тем не менее это действительно HTML, с которым вам придется иметь дело. Вы могли бы, конечно, придумать regex для его разбора, но, как уже предлагали другие, использовать реальный парсер HTML просто ооочень проще.
Я придумал вот это:
<(?!\/?p(?=>|\s.*>))\/?.*?>
x/
< # Match open angle bracket
(?! # Negative lookahead (Not matching and not consuming)
\/? # 0 or 1 /
p # p
(?= # Positive lookahead (Matching and not consuming)
> # > - No attributes
| # or
\s # whitespace
.* # anything up to
> # close angle brackets - with attributes
) # close positive lookahead
) # close negative lookahead
# if we have got this far then we don't match
# a p tag or closing p tag
# with or without attributes
\/? # optional close tag symbol (/)
.*? # and anything up to
> # first closing tag
/
Это теперь будет бороться с тегами П С или без атрибутов и закрывающим тегами P, но будет соответствовать заранее и похожие теги, с атрибутами или без.
Он не удаляет атрибуты, но мои исходные данные их не помещают. Я могу изменить это позже, чтобы сделать это, но пока этого будет достаточно.
Я использовал Xetius regex, и он отлично работает. За исключением некоторых flex сгенерированных тегов, которые могут быть :
без каких-либо пространств внутри. Я пытался исправить это с помощью простого ? после \s и похоже, что это работает :
<(?!\/?p(?=>|\s?.*>))\/?.*?>
Я использую его, чтобы очистить теги от flex сгенерированного html текста, поэтому я также добавил больше исключенных тегов :
<(?!\/?(p|a|b|i|u|br)(?=>|\s?.*>))\/?.*?>
Не знаю, почему вы хотите сделать это - regex для HTML дезинфекция не всегда лучший метод (вы должны помнить, чтобы очистить атрибуты и такие, удалить javascript: hrefs и подобные)... но, a regex, чтобы соответствовать тегам HTML, которые не являются <p></p> :
(<[^pP].*?>|</[^pP]>)
Многословный:
(
< # < opening tag
[^pP].*? # p non-p character, then non-greedy anything
> # > closing tag
| # ....or....
</ # </
[^pP] # a non-p tag
> # >
)
Поскольку HTML не является регулярным языком, я бы не ожидал, что регулярное выражение будет очень хорошо справляться с его соответствием. Возможно, они справятся с этой задачей (хотя я в этом не уверен), но я хотел бы посмотреть в другом месте; я уверен, что perl должен иметь некоторые библиотеки off-the-shelf для манипулирования HTML.
В любом случае, я бы подумал, что вы хотите сопоставить </?(p.+|.*)(\s*.*)> не жадно (я не знаю причуды синтаксиса регулярных выражений perl, поэтому не могу помочь дальше). Я предполагаю, что \s означает whitespace. А может, и нет. В любом случае, вам нужно что-то, что будет соответствовать атрибутам, смещенным от имени тега на whitespace. Но это гораздо сложнее, поскольку люди часто помещают неэкранированные угловые скобки внутри скриптов и комментариев и, возможно, даже цитируют значения атрибутов, которые вы не хотите сопоставлять.
Так что, как я уже сказал, Я не думаю, что регулярные выражения являются правильным инструментом для этой работы.
Предполагая, что это будет работать в PERL, как и в языках, которые утверждают, что используют PERL-совместимый синтаксис:
/<\/?[^p][^>]*>/
EDIT:
Но это не будет соответствовать тегу <pre> или <param> , к сожалению.
Может быть, вот это?
/<\/?(?!p>|p )[^>]+>/
Это должно охватывать <p> теги, которые также имеют атрибуты.
Оригинал regex можно заставить работать с очень небольшим усилием:
<(?>/?)(?!p).+?>
Проблема была в том, что /? (или \?) отказался от того, что он соответствовал, когда утверждение после него потерпело неудачу. Использование группы без обратного отслеживания (?>...) вокруг него заботится о том, чтобы он никогда не выпускал соответствующий Слэш, поэтому (?!p) утверждение всегда привязано к началу текста тега.
(Тем не менее я согласен, что в целом разбор HTML с помощью регулярных выражений-это не лучший способ).
Ксетий, воскрешая этот древний вопрос, потому что у него было простое решение, о котором не упоминалось. (Я нашел ваш вопрос, когда проводил некоторые исследования для задания regex bounty quest .)
Со всеми отказами от использования regex для разбора html, вот простой способ сделать это.
#!/usr/bin/perl
$regex = '(<\/?p[^>]*>)|<[^>]*>';
$subject = 'Bad html <a> </I> <p>My paragraph</p> <i>Italics</i> <p class="blue">second</p>';
($replaced = $subject) =~ s/$regex/$1/eg;
print $replaced . "\n";
Увидеть это демо
Ссылка
Как соответствовать шаблону за исключением ситуаций s1, s2, s3
Как соответствовать шаблону разве что...
Вероятно, вам также следует удалить все атрибуты на теге <p>, так как кто-то плохой может сделать что-то вроде:
<p onclick="document.location.href='http://www.evil.com'">Clickable text</p>
Самый простой способ сделать это-использовать предложенный здесь regex человек для поиска <p> тегов с атрибутами и заменить их <p> тегами без атрибутов. Просто на всякий случай.