RegEx соответствует открытым тегам, кроме автономных тегов XHTML

В mongoengine вам следует просто использовать экземпляр ссылочного объекта. Он должен иметь идентификатор. Предположим, что автор является экземпляром документа Author. Поэтому, используя это:

Post.objects(author__eq=author)

, вы можете просмотреть все сообщения этого автора. Post.author должен быть определен как ReferenceField

1324
задан 11 revs, 7 users 58% 26 May 2012 в 20:37
поделиться

22 ответа

Вы не можете разобрать [X] HTML с помощью регулярного выражения. Потому что HTML не может быть проанализирован с помощью регулярного выражения. Regex не является инструментом, который можно использовать для правильного синтаксического анализа HTML. Как я уже много раз отвечал на вопросы HTML и регулярных выражений, использование регулярных выражений не позволит вам использовать HTML. Регулярные выражения - это инструмент, который недостаточно сложен для понимания конструкций, используемых HTML. HTML не является обычным языком и поэтому не может быть проанализирован с помощью регулярных выражений. Запросы с регулярными выражениями не способны разбивать HTML на его значимые части. столько раз, но меня это не касается. Даже усовершенствованные нерегулярные регулярные выражения, используемые Perl, не подходят для анализа HTML. Ты никогда не заставишь меня сломаться. HTML - это язык с достаточной сложностью, поэтому его нельзя проанализировать с помощью регулярных выражений. Даже Джон Скит не может анализировать HTML с помощью регулярных выражений. Каждый раз, когда вы пытаетесь разобрать HTML с помощью регулярных выражений, нечестивый ребенок плачет кровью девственниц, и русские хакеры взламывают ваше веб-приложение. Анализ HTML с помощью регулярного выражения вызывает испорченные души в царство живых. HTML и регулярное выражение идут рука об руку, как любовь, брак и ритуальное детоубийство.

не может удержать это слишком поздно. Сила регулярного выражения и HTML вместе в одном концептуальном пространстве разрушит ваш разум, как жидкая замазка. Если вы анализируете HTML с помощью регулярного выражения, вы поддаетесь Им и их кощунственным способам, обрекающим всех нас на бесчеловечный труд для Того, чье Имя не может быть выражено в Основном Многоязычном Плане, - он придет. HTML-plus-regexp сжижает нервы разумного, пока вы наблюдаете, как ваша психика увядает от натиска ужаса. Синтаксические анализаторы HTML на основе регулярных выражений - это рак, убивающий StackOverflow слишком поздно, слишком поздно мы не можем спасти трансформация ребенка гарантирует, что регулярное выражение поглотит всю живую ткань (за исключением HTML, который он не может, как было предсказано ранее) дорогой господин, помоги нам, как можно выжить в этой беде использование регулярных выражений для синтаксического анализа HTML обрек человечество на вечность ужасных пыток и дыр в безопасности с использованием rege x в качестве инструмента для процесс HTML устанавливает разрыв ch между этим миром и царством ужасных прерываний (таких как объекты SGML, ̶̧̨̱̹̭̯ͧ̾ͬC̷̙̲̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̲̖͊̒ͪͩͬ̚̚͜Ȇ̴̟̟͙̞ͩ͌͝ S̨̥̫͎̭ͯ̿̔̀ͅ


Пробовали ли вы использовать вместо него синтаксический анализатор XML?


Примечание модератора

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

4419
ответ дан 19 December 2019 в 20:14
поделиться

Мне кажется, вы пытаетесь сопоставить теги без "/" в конце. Попробуйте следующее:

<([a-zA-Z][a-zA-Z0-9]*)[^>]*(?<!/)>
53
ответ дан 19 December 2019 в 20:14
поделиться

W3C объясняет синтаксический анализ в форме псевдо-регулярного выражения:
Ссылка W3C

Перейдите по ссылкам var для QName , S и Атрибут для получения более четкого изображения.
На основе этого вы можете создать довольно хорошее регулярное выражение для обработки таких вещей, как удаление тегов.

123
ответ дан 19 December 2019 в 20:14
поделиться

Вы хотите, чтобы перед первым > не ставился / . Посмотрите здесь , чтобы узнать, как это сделать. Это называется отрицательным ретроспективным просмотром.

Однако наивная реализация этого приведет к сопоставлению в этом примере документа

<foo><bar/></foo>

. Не могли бы вы предоставить немного больше информации о проблема, которую вы пытаетесь решить? Вы программно перебираете теги?

135
ответ дан 19 December 2019 в 20:14
поделиться

Раньше я использовал инструмент с открытым исходным кодом под названием HTMLParser . Он разработан для анализа HTML различными способами и достаточно хорошо выполняет эту задачу. Он может анализировать HTML как разные триноды, и вы можете легко использовать его API для получения атрибутов из узла. Проверьте это и посмотрите, поможет ли это вам.

89
ответ дан 19 December 2019 в 20:14
поделиться
<?php
$selfClosing = explode(',', 'area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed');

$html = '
<p><a href="#">foo</a></p>
<hr/>
<br/>
<div>name</div>';

$dom = new DOMDocument();
$dom->loadHTML($html);
$els = $dom->getElementsByTagName('*');
foreach ( $els as $el ) {
    $nodeName = strtolower($el->nodeName);
    if ( !in_array( $nodeName, $selfClosing ) ) {
        var_dump( $nodeName );
    }
}

Вывод:

string(4) "html"
string(4) "body"
string(1) "p"
string(1) "a"
string(3) "div"

В основном просто определите имена узлов элементов, которые являются самозакрывающимися, загружают всю строку html в библиотеку DOM, захватывают все элементы, проходят цикл и отфильтровывают те, которые не являются самозакрывающимися, и работают с ними.

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

153
ответ дан 19 December 2019 в 20:14
поделиться

Я не знаю, в чем конкретно вам это нужно, но если вы также используете .NET, не могли бы вы использовать Html Agility Pack ?

Отрывок:

Это библиотека кода .NET, которая позволяет вы должны разбирать HTML "вне Интернета" файлы. Парсер очень терпимый с "реальным" искаженным HTML.

148
ответ дан 19 December 2019 в 20:14
поделиться

Попробуйте:

<([^\s]+)(\s[^>]*?)?(?<!/)>

Он похож на ваш, но последний > не должен стоять после косой черты, а также принимает h1 .

180
ответ дан 19 December 2019 в 20:14
поделиться

Я предлагаю использовать QueryPath для синтаксического анализа XML и HTML в PHP. По сути, это тот же синтаксис, что и jQuery, только на стороне сервера.

257
ответ дан 19 December 2019 в 20:14
поделиться

Если вам это нужно для PHP:

Функции PHP DOM не будут работать должным образом, если они не будут правильно отформатированы в XML. Неважно, насколько лучше их использование для остального человечества.

simplehtmldom - это хорошо, но я обнаружил, что он немного глючит, и он требует большого объема памяти [Будет вылетать на больших страницах.]

Я никогда не использовал querypath , поэтому не могу комментировать его полезность.

Еще один вариант, который стоит попробовать - мой DOMParser , который очень мало использует ресурсы, и какое-то время я с удовольствием использую его. Простой в освоении и мощный.

Для Python и Java были опубликованы похожие ссылки.

Для тех, кто проголосовал против - я написал свой класс только тогда, когда парсеры XML оказались неспособными выдержать реальное использование.

106
ответ дан 19 December 2019 в 20:14
поделиться

Заявление об ограничении ответственности : используйте синтаксический анализатор, если у вас есть возможность. Тем не менее ...

Это регулярное выражение, которое я использую (!) Для сопоставления тегов HTML:

<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>

Возможно, он не идеален, но я прогнал этот код через лот HTML. Обратите внимание, что он даже улавливает странные вещи, такие как , которые появляются в Интернете.

Я думаю, чтобы он не соответствовал самодостаточным тегам, вы либо захотите использовать отрицательный взгляд назад Коби :

<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+(?<!/\s*)>

или просто комбинировать, если и если нет.

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

Предостережение : я должен отметить, что это регулярное выражение все еще не работает при наличии блоков CDATA, комментариев, и элементы сценария и стиля. Хорошие новости: от них можно избавиться с помощью регулярного выражения ...

1061
ответ дан 19 December 2019 в 20:14
поделиться

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

Если у вас есть небольшой набор HTML-страниц, с которых вы хотите очистить данные, а затем поместить их в базу данных, регулярные выражения могут работать нормально. Например, недавно я хотел получить имена, партии и округа австралийских федеральных представителей, которые я получил с веб-сайта парламента. Это была ограниченная разовая работа.

Регулярные выражения у меня отлично работали, и их очень быстро настраивали.

Если у вас есть небольшой набор HTML-страниц, с которых вы хотите очистить данные, а затем поместить их в базу данных, регулярные выражения могут работать нормально. Например, недавно я хотел получить имена, партии и округа австралийских федеральных представителей, которые я получил с веб-сайта парламента. Это была ограниченная разовая работа.

Регулярные выражения у меня отлично работали, и их очень быстро настраивали.

Если у вас есть небольшой набор HTML-страниц, с которых вы хотите очистить данные, а затем поместить их в базу данных, регулярные выражения могут работать нормально. Например, недавно я хотел получить имена, партии и округа австралийских федеральных представителей, которые я получил с веб-сайта парламента. Это была ограниченная разовая работа.

Регулярные выражения у меня отлично работали, и их очень быстро настраивали.

3186
ответ дан 19 December 2019 в 20:14
поделиться

Я думаю, что недостаток здесь в том, что HTML - это грамматика Хомского типа 2 (контекстно-свободная грамматика) , а RegEx - это грамматика Хомского типа 3 (обычная грамматика) . Поскольку грамматика типа 2 фундаментально более сложна, чем грамматика типа 3 (см. иерархию Хомского ), математически невозможно проанализировать XML с помощью RegEx.

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

Поскольку грамматика типа 2 фундаментально сложнее, чем грамматика типа 3 (см. иерархию Хомского ), математически невозможно проанализировать XML с помощью RegEx.

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

Поскольку грамматика типа 2 фундаментально более сложна, чем грамматика типа 3 (см. иерархию Хомского ), математически невозможно проанализировать XML с помощью RegEx.

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

1997
ответ дан 19 December 2019 в 20:14
поделиться

Когда мне нужно быстро извлечь что-то из HTML-документа, я использую Tidy для преобразования его в XML, а затем использую XPath или XSLT, чтобы получить то, что мне нужно. В вашем случае это будет примерно так:

//p/a[@href='foo']
91
ответ дан 19 December 2019 в 20:14
поделиться

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

Предлагаемый регекс неверен, однако:

<([a-z]+) *[^/]*?>

Если вы добавите что-то в регекс, путем обратного слежения он может быть вынужден соответствовать таким глупым вещам, как >, [^/] - это слишком неудобно. Также обратите внимание, что <пробел>*[^/]* является избыточным, так как [^/]* может также совпадать с пробелами.

Мое предложение было бы

<([a-z]+)[^>]*(?<!/)>

Где (? - это (в регексах Perl) отрицательный взгляд сзади. Оно гласит "a <, затем слово, затем все, что не является a >, последним из которых может не быть a /, за которым следует >".

Обратите внимание, что это разрешает такие вещи как (так же как и оригинальный регекс), так что если Вы хотите что-то более ограничительное, Вам нужно построить регекс, чтобы соответствовать парам атрибутов, разделенным пробелами.

216
ответ дан 19 December 2019 в 20:14
поделиться

Как уже указывали многие, HTML не является обычным языком, что может сильно затруднить его разбор. Мое решение заключается в том, чтобы превратить его в обычный язык с помощью аккуратной программы, а затем использовать парсер XML для получения результатов. Для этого есть много хороших вариантов. Моя программа написана с использованием Java с библиотекой jtidy для преобразования HTML в XML, а затем Jaxen для xpath в результат.

62
ответ дан 19 December 2019 в 20:14
поделиться

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

Есть окончательный пост в блоге о согласовании внутренних элементов HTML, написанный Стивеном Левитаном.

49
ответ дан 19 December 2019 в 20:14
поделиться

В оболочке вы можете проанализировать HTML с помощью sed :

  1. Turing.sed
  2. Написать Парсер HTML (домашнее задание)
  3. ???
  4. Прибыль!

По теме (почему не следует использовать совпадение регулярных выражений):

295
ответ дан 19 December 2019 в 20:14
поделиться

Здесь есть несколько хороших регулярных выражений для замены HTML на BBCode . Для всех, кто говорит против, обратите внимание, что он не пытается полностью разобрать HTML, просто чтобы дезинфицировать его. Он, вероятно, может позволить себе уничтожить теги, которые его простой "синтаксический анализатор" не может понять.

Например:

$store =~ s/http:/http:\/\//gi;
$store =~ s/https:/https:\/\//gi;
$baseurl = $store;

if (!$query->param("ascii")) {
    $html =~ s/\s\s+/\n/gi;
    $html =~ s/<pre(.*?)>(.*?)<\/pre>/\[code]$2\[\/code]/sgmi;
}

$html =~ s/\n//gi;
$html =~ s/\r\r//gi;
$html =~ s/$baseurl//gi;
$html =~ s/<h[1-7](.*?)>(.*?)<\/h[1-7]>/\n\[b]$2\[\/b]\n/sgmi;
$html =~ s/<p>/\n\n/gi;
$html =~ s/<br(.*?)>/\n/gi;
$html =~ s/<textarea(.*?)>(.*?)<\/textarea>/\[code]$2\[\/code]/sgmi;
$html =~ s/<b>(.*?)<\/b>/\[b]$1\[\/b]/gi;
$html =~ s/<i>(.*?)<\/i>/\[i]$1\[\/i]/gi;
$html =~ s/<u>(.*?)<\/u>/\[u]$1\[\/u]/gi;
$html =~ s/<em>(.*?)<\/em>/\[i]$1\[\/i]/gi;
$html =~ s/<strong>(.*?)<\/strong>/\[b]$1\[\/b]/gi;
$html =~ s/<cite>(.*?)<\/cite>/\[i]$1\[\/i]/gi;
$html =~ s/<font color="(.*?)">(.*?)<\/font>/\[color=$1]$2\[\/color]/sgmi;
$html =~ s/<font color=(.*?)>(.*?)<\/font>/\[color=$1]$2\[\/color]/sgmi;
$html =~ s/<link(.*?)>//gi;
$html =~ s/<li(.*?)>(.*?)<\/li>/\[\*]$2/gi;
$html =~ s/<ul(.*?)>/\[list]/gi;
$html =~ s/<\/ul>/\[\/list]/gi;
$html =~ s/<div>/\n/gi;
$html =~ s/<\/div>/\n/gi;
$html =~ s/<td(.*?)>/ /gi;
$html =~ s/<tr(.*?)>/\n/gi;

$html =~ s/<img(.*?)src="(.*?)"(.*?)>/\[img]$baseurl\/$2\[\/img]/gi;
$html =~ s/<a(.*?)href="(.*?)"(.*?)>(.*?)<\/a>/\[url=$baseurl\/$2]$4\[\/url]/gi;
$html =~ s/\[url=$baseurl\/http:\/\/(.*?)](.*?)\[\/url]/\[url=http:\/\/$1]$2\[\/url]/gi;
$html =~ s/\[img]$baseurl\/http:\/\/(.*?)\[\/img]/\[img]http:\/\/$1\[\/img]/gi;

$html =~ s/<head>(.*?)<\/head>//sgmi;
$html =~ s/<object>(.*?)<\/object>//sgmi;
$html =~ s/<script(.*?)>(.*?)<\/script>//sgmi;
$html =~ s/<style(.*?)>(.*?)<\/style>//sgmi;
$html =~ s/<title>(.*?)<\/title>//sgmi;
$html =~ s/<!--(.*?)-->/\n/sgmi;

$html =~ s/\/\//\//gi;
$html =~ s/http:\//http:\/\//gi;
$html =~ s/https:\//https:\/\//gi;

$html =~ s/<(?:[^>'"]*|(['"]).*?\1)*>//gsi;
$html =~ s/\r\r//gi;
$html =~ s/\[img]\//\[img]/gi;
$html =~ s/\[url=\//\[url=/gi;
71
ответ дан 19 December 2019 в 20:14
поделиться

По вопросу о методах RegExp для синтаксического анализа (x) HTML, ответ на всех, кто говорил о некоторых ограничениях: вы недостаточно обучены, чтобы управлять силой этого мощное оружие, поскольку НИКТО здесь не говорил о рекурсии .

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

Прочитав несколько сообщений, я первым делом искал строку «? R» в этой ветке. Второй - искать на предмет «рекурсии».
Нет, святая корова, совпадений не найдено.
Поскольку никто не упоминал об основном механизме, на котором построен синтаксический анализатор, я вскоре понял, что никто не понял сути.

Если синтаксическому анализатору (x) HTML требуется рекурсия, синтаксического анализатора RegExp без рекурсии для этой цели недостаточно. Это простая конструкция.

Черное искусство RegExp трудно освоить , так что, возможно, есть дополнительные возможности, которые мы упустили, пытаясь и тестируя наше личное решение для захвата всей сети в одной руке ... Что ж, я конечно :)

Вот волшебный узор:

$pattern = "/<([\w]+)([^>]*?)(([\s]*\/>)|(>((([^<]*?|<\!\-\-.*?\-\->)|(?R))*)<\/\\1[\s]*>))/s";

Просто попробуйте.
Он записывается как строка PHP, поэтому модификатор «s» заставляет классы включать символы новой строки.
Вот пример примечания к руководству по PHP , которое я написал в январе: Ссылка

(Будьте осторожны, в этом примечании я ошибочно использовал модификатор «m»; его следует стереть, несмотря на то, что он отбрасывается механизмом RegExp, поскольку не использовались привязки ^ или $).

Теперь мы могли бы говорить об ограничениях этого метода с более информированной точки зрения:

  1. в соответствии с конкретной реализацией механизма RegExp, рекурсия может иметь ограничение на количество анализируемых вложенных шаблонов. , но это зависит от используемого языка
  2. , хотя поврежденный (x) HTML не приводит к серьезным ошибкам, он не очищен .

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

67
ответ дан 19 December 2019 в 20:14
поделиться

Вот парсер на основе PHP, который разбирает HTML, используя некий нечестивый regex. Как автор этого проекта, я могу сказать, что парсить HTML с помощью regex можно, но не эффективно. Если вам нужно решение на стороне сервера (как я сделал для своего wp-Typography WordPress plugin), то вот это работает.

74
ответ дан 19 December 2019 в 20:14
поделиться

Это может сделать:

<.*?[^/]>

Или без закрывающих тегов:

<[^/].*?[^/]>

Что с пламенными войнами в синтаксических анализаторах HTML? Анализаторы HTML должны проанализировать (и перестроить!) Весь документ, прежде чем он сможет классифицировать ваш поиск. При определенных обстоятельствах регулярные выражения могут быть более быстрыми / элегантными. Мои 2 цента ...

33
ответ дан 19 December 2019 в 20:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: