Pull to refresh

Comments 5

Для парсинга 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 определится?

Sign up to leave a comment.

Articles