HTML / XML поділяється на розмітку та вміст. Regex корисний лише для розбору лексичного розбору тегів. Я думаю, ви могли б вивести вміст. Це був би хороший вибір для аналізатора SAX. Теги та контент можуть бути доставлені на визначену користувачем функцію, де можна відстежувати введення / закриття елементів.
Що стосується просто розбору тегів, це можна зробити за допомогою регулярного вираження та використовувати для викреслення тегів з документа.
За роки тестування я виявив секрет того, як браузери аналізують теги, як добре, так і погано сформовані.
Нормальні елементи розбираються з цією формою:
Ядро цих тегів використовує цей регулярний вираз
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| [^>]?
)+
Ви помітите це [^>]?
як одне з чергувань. Це буде відповідати незбалансованим цитатам з неправильно сформованих тегів.
Це також є єдиним коренем всього зла до регулярних виразів. Те, як воно використовується, викликає перешкоду, щоб задовольнити його жадібний, повинен відповідати кількісно визначеному контейнеру.
Якщо використовується пасивно, жодних проблем не виникає. Але якщо ви змусите щось збігатися, перетлумачивши його потрібним парним атрибутом / значенням і не забезпечивши належного захисту від зворотного відстеження, це кошмар поза контролем.
Це загальна форма лише для простих старих тегів. Помічаєте [\w:]
представницьку назву тегу? Насправді легальні символи, що представляють назву тегів, - це неймовірний список символів Unicode.
<
(?:
[\w:]+
\s+
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| [^>]?
)+
\s* /?
)
>
Вперед, ми також бачимо, що ви просто не можете шукати конкретний тег без аналізу ВСІХ тегів. Я маю на увазі, що ви могли б, але для цього доведеться використовувати комбінацію дієслів типу (* SKIP) (* FAIL), але все-таки всі теги мають бути розібрані.
Причина полягає в тому, що синтаксис тегів може бути прихований всередині інших тегів тощо.
Отже, для пасивного розбору всіх тегів потрібен регулярний вираз, як наведений нижче. Цей конкретний також відповідає невидимому вмісту .
Оскільки новий HTML або xml або будь-який інший розробляють нові конструкції, просто додайте їх як одне з чергувань.
Примітка веб-сторінки - я ніколи не бачив веб-сторінки (або xhtml / xml), з якою із цим
виникли проблеми. Якщо ви знайдете його, дайте мені знати.
Примітка про ефективність - Це швидко. Це найшвидший аналізатор тегів, який я бачив
(може бути, швидше, хто знає).
У мене є кілька конкретних версій. Він також чудовий як скрепер
(якщо ви практичний тип).
Повна сировина
<(?:(?:(?:(script|style|object|embed|applet|noframes|noscript|noembed)(?:\s+(?>"[\S\s]*?"|'[\S\s]*?'|(?:(?!/>)[^>])?)+)?\s*>)[\S\s]*?</\1\s*(?=>))|(?:/?[\w:]+\s*/?)|(?:[\w:]+\s+(?:"[\S\s]*?"|'[\S\s]*?'|[^>]?)+\s*/?)|\?[\S\s]*?\?|(?:!(?:(?:DOCTYPE[\S\s]*?)|(?:\[CDATA\[[\S\s]*?\]\])|(?:--[\S\s]*?--)|(?:ATTLIST[\S\s]*?)|(?:ENTITY[\S\s]*?)|(?:ELEMENT[\S\s]*?))))>
Форматований вигляд
<
(?:
(?:
(?:
# Invisible content; end tag req'd
( # (1 start)
script
| style
| object
| embed
| applet
| noframes
| noscript
| noembed
) # (1 end)
(?:
\s+
(?>
" [\S\s]*? "
| ' [\S\s]*? '
| (?:
(?! /> )
[^>]
)?
)+
)?
\s* >
)
[\S\s]*? </ \1 \s*
(?= > )
)
| (?: /? [\w:]+ \s* /? )
| (?:
[\w:]+
\s+
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| [^>]?
)+
\s* /?
)
| \? [\S\s]*? \?
| (?:
!
(?:
(?: DOCTYPE [\S\s]*? )
| (?: \[CDATA\[ [\S\s]*? \]\] )
| (?: -- [\S\s]*? -- )
| (?: ATTLIST [\S\s]*? )
| (?: ENTITY [\S\s]*? )
| (?: ELEMENT [\S\s]*? )
)
)
)
>