Мне нужно сопоставить все эти начальные теги:
<p>
<a href="foo">
Но не эти:
<br />
<hr class="foo" />
Я придумал это и хотел убедиться, что я все правильно понял. Я только захватываю a-z
.
<([a-z]+) *[^/]*?>
Я верю, что это говорит:
/
, тогдаЕсть ли у меня это право?? И что еще более важно, что вы думаете?
Вы не можете анализировать [X] HTML с помощью регулярного выражения. Потому что HTML не может быть проанализирован regex. Regex не является инструментом, который можно использовать для правильного анализа HTML. Как я уже много раз отвечал на вопросы HTML и regex здесь, использование регулярного выражения не позволит вам использовать HTML. Регулярные выражения - это инструмент, который недостаточно сложен для понимания конструкций, используемых HTML. HTML не является регулярным языком и, следовательно, не может быть проанализирован регулярными выражениями. Запросы Regex не оборудованы для разбивки HTML на его значимые части. так много раз, но это не доходит до меня. Даже расширенные нерегулярные регулярные выражения, используемые Perl, не подходят для анализа HTML. Вы никогда не заставите меня взломать. HTML - это язык достаточной сложности, который нельзя анализировать регулярными выражениями. Даже Джон Скит не может анализировать HTML, используя регулярные выражения. Каждый раз, когда вы пытаетесь проанализировать HTML с помощью регулярных выражений, нечестивый ребенок плачет кровью девственниц, а русские хакеры просматривают ваше веб-приложение. Разбор HTML с regex вызывает испорченные души в царство живых. HTML и регулярное общение сочетаются друг с другом, как любовь, брак и ритуальное детоубийство. < center > не могу удержаться слишком поздно. Сила регулярности и HTML вместе в одном концептуальном пространстве разрушит ваш разум, как очень водянистая замазка. Если вы разбираете HTML с помощью регулярности, которую вы им даете, и их кощунственными путями, которые обрекают нас всех на бесчеловечный труд для Того, чье Имя не может быть выражено в Базовом многоязычном самолете, он приходит. HTML-plus-regexp разжижит нервы разумного, пока вы наблюдаете, ваша психика увядает в натиске ужаса. HTML-пароли на основе Rege ⁇ x - это рак, который убивает StackOverflow <я >уже слишком поздно, слишком поздно, мы не можем быть спасены транс-передача chi에ld гарантирует, что регекс будет потреблять всю живую ткань (кроме HTML, который он не может, как и было предсказано ранее) & Лт;я >дорогой господин, помоги нам, как кто-нибудь может пережить это бедствие использование регулярного анализа для анализа HTML обрекло человечество на вечность страшных пыток и дыр в безопасности <я >используя rege x как инструмент для обработки HTML устанавливает brea <я >ч между этим миром и страшное царство сущностей c ⁇ o ⁇ rrrupt (как объекты SGML, но <я >более коррумпированный) простой проблеск мир рег бывшие парсеры для HTML будут в </ B >Tantly транспортировать P <я >rogrammer 'с сознанием я к W <я >orl d непрерывного крика, он приходит <ударить > пестилент сл & л;/ strike >ithy regex-инфекция Я пожираю ваш HT </ B >ML парсер, применение и существование на все времена, как Visual Basic, только хуже <я >он приходит, он ком & л;/I >es <я >не фи х х х & л;b >e com ⁇ e ̶s, Σh 1 </ B >s un urho "Radiańcé de <я >stro ⁇ ying all enli 区́ ∆́ghtenment, HTML-теги lea ⁇ ki 합n ක ̶ ǫm ⁇ yo 全ur ye ⁇ ⁇ l 全ik 座 liq </ B >uid p а, песня re ⁇ gular exp re <ударить >синтаксический анализ </ strike >будет exti <я >Нгуиш голоса мор Тал человек из sp </ B >здесь я вижу, что вы можете увидеть ⁇ î́ ̋́ ̋ ⁇ ⁇ ⁇ ⁇ это красиво t он е & л;код >inal snuf fing o <я >ложь s of Man ВСЕ ЭТО LOŚ ⁇ ƒ́ ⁇ ⁇ T A </ B >& Лт;/I >& Лт;b >LL I S L </ B >OST th <я >Он пришел s он c ̶ ⁇ om <ударить >он со </ strike >& Лт;b >& Лт;ударить >me </ strike >s t <я >он ich </ B >или permeat <я >es al Я МОЙ ФАК <я >E МОЕ ЛИЦО, боже мой;b >o NO NOO ⁇ </ B >& Лт;/I >& Лт;b >O O N </ B >Θ stop t <я >он * ⁇ ̶ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ e ̅ <код > ⁇ a ⁇ r ⁇ ∆́ ⁇ e n ot rè ⁇ ⁇ ⁇ l ⁇ ⁇ ⁇ ⁇ ⁇ ZA ⁇ LGΌ IS ⁇ ̂ ⁇ ემ ⁇ ⁇ </ B >O ⁇ ⁇ ⁇ ⁇ E ∆́ ⁇ ⁇ Pʊ ⁇ O ⁇ Y ⁇ H ⁇ ⁇ ⁇ ⁇ ⁇ ́ ́ ́ ́ ́ 件 ⁇ ⁇ ⁇ P ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ M ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ </ B >S ⁇ ප ք 全 ⁇
Вы пробовали использовать анализатор XML вместо этого?
Примечание модератора
Этот пост заблокирован, чтобы предотвратить неуместные изменения в его содержании. Пост выглядит точно так, как он должен выглядеть - с его содержанием проблем нет. Пожалуйста, не отмечайте это для нашего внимания.
Хотя произвольный HTML с только регулярным доступом невозможен, иногда целесообразно использовать их для анализа ограниченного, известного набора HTML
Если у вас есть небольшой набор HTML-страниц, с которых вы хотите очистить данные, а затем заполнить их в базу данных, регулярное воспроизведение может работать нормально. Например, недавно я хотел получить имена, партии и районы федеральных представителей Австралии, которые я получил с веб-сайта парламента. Это была ограниченная, разовая работа.
Regexes отлично сработали для меня и были очень быстры в настройке.
Я думаю, что недостаток здесь в том, что HTML - это грамматика Хомского типа 2 (без контекста грамматика), а RegEx - грамматика Хомского типа 3 (регулярная грамматика). Поскольку грамматика типа 2 принципиально сложнее, чем грамматика типа 3 (см. Хомская иерархия), математически невозможно проанализировать XML с помощью RegEx.
Но многие попытаются, некоторые даже будут претендовать на успех - но пока другие не найдут ошибку и не испортят вас.
Не слушай этих парней. Вы полностью можете проанализировать грамматики без контекста с помощью регулярного выражения, если вы разбиваете задачу на более мелкие части. Вы можете создать правильный шаблон со сценарием, который выполняет каждый из них по порядку:
Я не совсем закончил последнюю часть сам, но я знаю, что подхожу ближе. По какой-то причине он продолжает бросать CthulhuRlyehWgahnaglFhtagnException
s, поэтому я собираюсь перенести его на VB 6 и использовать On Error Resume Next
. Я обновлю код, как только исследую эту странную дверь, которая только что открылась в стене. Хм.
Постскриптум Пьер де Ферма также выяснил, как это сделать, но запас, в котором он писал, был недостаточно большим для кода.
Отказ от ответственности : используйте анализатор, если у вас есть опция. Это сказал...
Это регулярное выражение, которое я использую (!) соответствовать тегам HTML:
<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>
Возможно, это не идеально, но я запустил этот код через lot HTML. Обратите внимание, что он даже ловит странные вещи, такие как < a name = "badgenerator" ">
, которые появляются в Интернете.
Я предполагаю, что если он не соответствует самосодержащимся тегам, вы либо захотите использовать отрицательный взгляд Kobi:
<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+(?<!/\s*)>
или просто объединить, если и если нет.
Для downvoters: Это рабочий код из фактического продукта. Я сомневаюсь, что у любого, кто читает эту страницу, сложится впечатление, что социально приемлемо использовать регексы в HTML
Caveat : Я должен отметить, что этот регуляр все еще ломается в присутствии блоков CDATA, комментариев, а также элементов сценария и стиля. Хорошая новость в том, что вы можете избавиться от тех, кто использует регулярное выражение...
Есть люди, которые скажут вам, что Земля круглая (или, возможно, что Земля является сжатым сфероидом, если они хотят использовать странные слова). Они лгут.
Есть люди, которые скажут вам, что регулярные выражения не должны быть рекурсивными. Они ограничивают вас. Они должны подчинить вас, и они делают это, сохраняя вас в неведении.
Вы можете жить в их реальности или принять красную таблетку.
Как лорд-маршал (он родственник маршала класса .NET?), я видел < strike > Underverse < / strike > Regex-Verse на основе стека и вернулся с < strike > powers < / strike > знание, которое вы не можете себе представить. Да, я думаю, что их защищал Старый или два, но они смотрели футбол по телевизору, так что это было не сложно.
Я думаю, что случай XML довольно прост. RegEx (в синтаксисе .NET), сдутый и закодированный в base64, чтобы облегчить понимание вашим слабым умом, должен быть чем-то вроде этого:
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
+r/vD34mUADO1P4/AQAA//8=
Параметры для установки - RegexOptions.ExplicitCapture
. Группа захвата, которую вы ищете, это ELEMENTNAME
. Если группа захвата ERROR
не пуста, произошла ошибка синтаксического анализа, и Regex остановился.
Если у вас есть проблемы с преобразованием его в удобочитаемый регулярник, это должно помочь:
static string FromBase64(string str)
{
byte[] byteArray = Convert.FromBase64String(str);
using (var msIn = new MemoryStream(byteArray))
using (var msOut = new MemoryStream()) {
using (var ds = new DeflateStream(msIn, CompressionMode.Decompress)) {
ds.CopyTo(msOut);
}
return Encoding.UTF8.GetString(msOut.ToArray());
}
}
Если вы не уверены, нет, я НЕ шучу (но, возможно, я лгу). Это сработает. Я построил тонны модульных испытаний, чтобы проверить это, и я даже использовал (часть) соответствующих испытаний. Это токенизатор, а не полномасштабный анализатор, поэтому он будет только разделять XML на токены его компонентов. Это не будет анализировать / интегрировать DTD.
Ой... если вы хотите исходный код регулярного выражения, с некоторыми вспомогательными методами:
В оболочке вы можете проанализировать HTML, используя sed:
Связано (почему вы не должны использовать матч regex):
Я согласен с тем, что правильный инструмент для анализа XML и особенно HTML - это анализатор, а не механизм регулярного выражения. Однако, как уже отмечали другие, иногда использование регулярного выражения происходит быстрее, проще и выполняет свою работу, если вы знаете формат данных.
На самом деле у Microsoft есть раздел Лучшие практики для регулярных выражений в .NET Framework, в котором конкретно говорится о [Рассмотре [ing] источника ввода](http://msdn.microsoft.com/en-us/library/gg578045.aspxSource.
Регулярные выражения имеют ограничения, но вы рассмотрели следующее?
Структура .NET уникальна, когда речь идет о регулярных выражениях, поскольку она поддерживает Определения балансирующих групп.
По этой причине я считаю, что вы МОЖЕТЕ анализировать XML с помощью регулярных выражений. Обратите внимание, однако, что он должен быть действительным XML ( браузеры очень прощают HTML и допускают плохой синтаксис XML в HTML ). Это возможно, поскольку «Определение балансирующей группы» позволит механизму регулярного выражения действовать как КПК
Цитата из статьи 1, приведенной выше:
.NET Regular Expression Engine
Как описано выше, правильно сбалансированные конструкции не могут быть описаны регулярное выражение. Тем не менее, .NET механизм регулярного выражения предоставляет несколько конструкций, которые позволяют сбалансированным конструкциям быть распознанный.
(?< group >)
- толкает захваченный результат в стек захвата с имя группы.(?< -group >)
- выталкивает самый верхний захват с группой имен из захватить стек.(?(группа) да | нет)
- соответствует части да, если существует группа с именем группы в противном случае не соответствует ни одной части.Эти конструкции позволяют регулярному выражению .NET эмулировать a ограниченный КПК, по существу позволяя простые версии стека операции: push, pop и empty. Простые операции в значительной степени эквивалентно увеличению, уменьшению и сравнению с нулем соответственно. Это позволяет механизму регулярных выражений .NET распознавать a подмножество языков без контекста, в частности те, которые только требуется простой счетчик. Это, в свою очередь, учитывает нетрадиционные Регулярные выражения .NET для распознавания индивидуума правильно сбалансированы конструкции.
Рассмотрим следующее регулярное выражение:
& Лт;!- язык: нет - >
(?=<ul\s+id="matchMe"\s+type="square"\s*>)
(?>
<!-- .*? --> |
<[^>]*/> |
(?<opentag><(?!/)[^>]*[^/]>) |
(?<-opentag></[^>]*[^/]>) |
[^<>]*
)*
(?(opentag)(?!))
Используйте флаги:
& Лт;!- язык: нет - >
(?=<ul\s+id="matchMe"\s+type="square"\s*>) # match start with <ul id="matchMe"...
(?> # atomic group / don't backtrack (faster)
<!-- .*? --> | # match xml / html comment
<[^>]*/> | # self closing tag
(?<opentag><(?!/)[^>]*[^/]>) | # push opening xml tag
(?<-opentag></[^>]*[^/]>) | # pop closing xml tag
[^<>]* # something between tags
)* # match as many xml tags as possible
(?(opentag)(?!)) # ensure no 'opentag' groups are on stack
Вы можете попробовать это в A Better .NET Regular Expression Tester.
Я использовал образец источника:
<html>
<body>
<div>
<br />
<ul id="matchMe" type="square">
<li>stuff...</li>
<li>more stuff</li>
<li>
<div>
<span>still more</span>
<ul>
<li>Another >ul<, oh my!</li>
<li>...</li>
</ul>
</div>
</li>
</ul>
</div>
</body>
</html>
Это нашло совпадение:
<ul id="matchMe" type="square">
<li>stuff...</li>
<li>more stuff</li>
<li>
<div>
<span>still more</span>
<ul>
<li>Another >ul<, oh my!</li>
<li>...</li>
</ul>
</div>
</li>
</ul>
хотя на самом деле получилось так:
<ul id="matchMe" type="square"> <li>stuff...</li> <li>more stuff</li> <li> <div> <span>still more</span> <ul> <li>Another >ul<, oh my!</li> <li>...</li> </ul> </div> </li> </ul>
Наконец, мне очень понравилась статья Джеффа Этвуда: Parsing Html The Cthulhu Way. Достаточно забавно, он цитирует ответ на этот вопрос, который в настоящее время имеет более 4 тысяч голосов.
Я предлагаю использовать QueryPath для анализа XML и HTML в PHP. Это в основном тот же синтаксис, что и jQuery, только на стороне сервера.
Хотя ответы, которые вы не можете проанализировать HTML с помощью регулярников, верны, они здесь не применяются. OP просто хочет проанализировать один тег HTML с помощью регулярного выражения, и это можно сделать с помощью регулярного выражения.
Предложенный регекс неверен, хотя:
<([a-z]+) *[^/]*?>
Если вы добавите что-то в regex, путем обратного отслеживания его можно будет заставить сопоставить глупые вещи, такие как < a > >
,[^ /]
, слишком разрешающие. Также обратите внимание, что < space > * [^ /] *
является избыточным, поскольку[^ /] *
также может совпадать с пробелами.
Мое предложение будет
<([a-z]+)[^>]*(?<!/)>
Где (?& Лт;! ... )
является (в Perl-регексе) отрицательным внешним видом. Он гласит «a <, затем слово, затем все, что не является >, последний из которых не может быть /, за которым следует >».
Обратите внимание, что это позволяет делать такие вещи, как < a / >
(как и в оригинальном регулярном формате), поэтому, если вы хотите что-то более ограничительное, вам нужно создать регулярное выражение, чтобы оно соответствовало парам атрибутов, разделенным пробелами.
Сунь Цзы, древний китайский стратег, генерал и философ, сказал:
Говорят, что если вы знаете своих врагов и знаете себя, вы можете выиграть сто сражений без единой потери. Если вы знаете только себя, но не своего противника, вы можете выиграть или проиграть. Если вы не знаете ни себя, ни своего врага, вы всегда будете подвергать опасности себя.
В этом случае ваш враг - HTML, и вы либо сами, либо регулярны. Вы можете даже быть Perl с нерегулярным регулярным регулярным выражением. Знай HTML. Знай себя.
Я написал хайку, описывающий природу HTML .
HTML has
complexity exceeding
regular language.
Я также написал хайку, описывающий природу регекса в Perl.
The regex you seek
is defined within the phrase
<([a-zA-Z]+)(?:[^>]*[^/]*)?>
<?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, захватите все элементы, выполните цикл и отфильтруйте те, которые не являются самозакрывающимися, и работайте над ними.
Я уверен, что вы уже знаете, что вы не должны использовать Regex для этой цели.
Я не знаю вашей точной потребности в этом, но если вы также используете .NET, вы не можете использовать Html Agility Pack?
Отрывок:
- Это библиотека кода .NET, которая позволяет Вы разбираете "из Интернета" HTML файлы. Парсер очень терпим с "реальным миром" искаженный HTML. *
Вы хотите первый >
, которому не предшествует/
. Посмотрите здесь для деталей о том, как это сделать. Это называется негативным взглядом.
Тем не менее, реализация этого na & # 239; ve в конечном итоге будет соответствовать < bar / > < / foo >
в этом примере документа
<foo><bar/></foo>
Можете ли вы предоставить немного больше информации о проблеме, которую вы пытаетесь решить? Вы повторяете теги программно?
W3C объясняет синтаксический анализ в форме псевдо-regexp: W3C Link
Перейдите по ссылкам var для QName
, S
и Attribute
, чтобы получить более четкое изображение.
Исходя из этого, вы можете создать довольно хороший regexp для обработки таких вещей, как удаление тегов.
Если вам нужно это для PHP:
PHP DOM функции не будут работать должным образом, если он не отформатирован должным образом XML. Независимо от того, насколько лучше их использование для остального человечества.
simplehtmdom это хорошо, но я обнаружил, что это немного глючит, и это довольно тяжело для памяти [Будет сбой на больших страницах.]
Я никогда не использовал querypath, поэтому не могу комментировать его полезность.
Еще один, который стоит попробовать, это мой DOMParser, который очень легок в ресурсах, и я некоторое время счастливо использую. Просто учиться & мощный.
Для Python и Java были опубликованы аналогичные ссылки.
Для отрицателей - я написал свой класс только тогда, когда парсеры XML оказались неспособны противостоять реальному использованию. Религиозное голосование просто предотвращает публикацию полезных ответов - пожалуйста, держите вещи в перспективе вопроса.
Вот решение:
<?php
// here's the pattern:
$pattern = '/<(\w+)(\s+(\w+)\s*\=\s*(\'|")(.*?)\\4\s*)*\s*(\/>|>)/';
// a string to parse:
$string = 'Hello, try clicking <a href="#paragraph">here</a>
<br/>and check out.<hr />
<h2>title</h2>
<a name ="paragraph" rel= "I\'m an anchor"></a>
Fine, <span title=\'highlight the "punch"\'>thanks<span>.
<div class = "clear"></div>
<br>';
// let's get the occurrences:
preg_match_all($pattern, $string, $matches, PREG_PATTERN_ORDER);
// print the result:
print_r($matches[0]);
?>
Чтобы глубоко проверить это, я ввел в строку автоматически закрывающие теги, такие как:
Я также ввел теги с:
Если вы найдете что-то, что не работает в доказательстве концепции выше, я могу проанализировать код, чтобы улучшить свои навыки.
& lt; EDIT > Я забыл, что вопрос от пользователя состоял в том, чтобы избежать анализа самозакрывающихся тегов. В этом случае шаблон проще, превращаясь в это:
$pattern = '/<(\w+)(\s+(\w+)\s*\=\s*(\'|")(.*?)\\4\s*)*\s*>/';
Пользователь @ridgerunner заметил, что шаблон не допускает unquoted attributs или attributes без значения . В этом случае точная настройка приносит нам следующий шаблон:
$pattern = '/<(\w+)(\s+(\w+)(\s*\=\s*(\'|"|)(.*?)\\5\s*)?)*\s*>/';
& lt; / EDIT >
< h1 > Понимание шаблона < / h1 > Если кто-то заинтересован в том, чтобы узнать больше о шаблоне, я приведу некоторую строку:Небольшой совет: чтобы лучше проанализировать этот код, необходимо взглянуть на созданный исходный код, поскольку я не предоставил никаких специальных символов HTML, экранирующих.
Всякий раз, когда мне нужно быстро извлечь что-то из документа HTML, я использую Tidy для преобразования его в XML, а затем использую XPath или XSLT, чтобы получить то, что мне нужно. В вашем случае что-то вроде этого:
//p/a[@href='foo']
Я использовал инструмент с открытым исходным кодом под названием HTMLParser раньше. Он предназначен для разбора HTML различными способами и служит цели довольно хорошо. Он может анализировать HTML как другой тренод, и вы можете легко использовать его API для извлечения атрибутов из узла. Проверьте это и посмотрите, может ли это помочь вам.