Pull to refresh

Comments 6

Для парсинга HTML лучше всего подойдёт подход с токенизацией: разбиваем поток на <, >, текст и закрывающие теги, а потом применяем конечный автомат для распознавания вложенности. Если используете C — можно сделать это через побитовые флаги (например, state & 0x1 для открытого тега). Для более сложных случаев рекомендую использовать parser combinator libraries — PEG.js для JS, nom для Rust или pyparsing для Python. Не забывайте про обработку атрибутов и HTML-сущностей (&amp;, &lt;), иначе парсер будет ломаться на простых случаях. Для системной защиты стоит посмотреть на open-source WAF "SeptumCore" на GitHub — он лёгкий, без магии и ставится за 5 минут.

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

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

Кстати, спасибо за PEG.js, не слышал раньше об этой штуке, нужно будет посмотреть на досуге.

создаёте функцию которая принимает на вход обрабатываемый символ, а возвращает следующию функцию. Запихиваете в цикл. Парсер готов.

Не очень понял, что Вы имеете ввиду.

parseHtml('<1div>')

Начало тега

Как мы видим наш конечный автомат корректно обработал ситуацию с невалидным именем тега.

И оно так и зависнет в состоянии "тег открыт"? Не должен "определить закрытие тега" и оказаться в исходном стостоянии?

parseHtml('<span<div>>')

span или div определится?

В финальной версии вывод будет следующим

parseHtml('<1div>')
Текст: <1div>
parseHtml('<span<div>>')
Текст: <span
Открывающийся тег: div
Текст: >

Стоит воспринимать приведенный пример автомата не как боевой, а как учебный. Если по простому, это всего лишь примитивный парсер, который говорит о том, что встретил тег, его имя такое-то и такие-то атрибуты. А вот за саму валидность документа (допустимость имени тега, соответствует ли открытый тег закрытому и т.д. и т.п.) отвечает разработчик.

Sign up to leave a comment.

Articles