Разбор HTML-документа в Bash-скрипте без регулярных выражений - PullRequest
1 голос
/ 23 февраля 2012

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

Почему я использую Bash (вы можете пропустить это, чтобы перейти к вопросу)

(отредактировано) Выбор использования Bash довольно произвольный.Я знаю, что работает Red Hat 5.5, поэтому я пишу сценарий Bash.У него есть интерпретатор PHP, но я решил не использовать PHP для этого, так как тот же сервер будет размещать сайт, который использует PHP и, вероятно, будет видеть большой трафик, поэтому я боюсь подключать сокет FastCGI каждыйчас выполнения этой операции (я не контролирую частоту выполнения скрипта, только то, что выполняется).Я также могу установить любой интерпретатор, который мне нужен (языки сценариев, которые я на самом деле знаю уже: Perl, Python, PHP, возможно Lua).Это, однако, другой вопрос.В этом вопросе предполагается, что я хочу использовать скрипт Bash.

Проблема

У меня есть файл основного шаблона, который выглядит примерно так:

<!DOCTYPE html PUBLIC .... >
<html lang="en" ...>
<head> ... </head>
<body>
    <div id=...></div>
    <div id=...></div>
</body>
</html>

Исходя из этого, мне нужно проанализировать верхнюю часть документа до </head>, вырезать несколько строк из этого раздела и добавить одну, заменить местозаполнитель <title> на фактический заголовок и сохранить его в файл.,Затем мне нужно разобрать <body> и сначала <div> как отдельный файл, а затем, наконец, второй <div> (в который мне также нужно внести некоторые изменения в нижний колонтитул страницы).Я буду отбрасывать </body> и </html>, так как этот шаблон на самом деле является частью двухслойного шаблона (в замененном заголовке страницы будет использоваться переменная Smarty для получения текста).

Загадка

Вопрос в том, есть ли более простой / лучший способ сделать это, чем регулярное выражение?Я знаю, что Bash предоставляет составные команды [[ htmlstring =~ "/regex/" ]] и ${BASH_REMATCH} для сопоставления или замены, но я также знаю, что синтаксический анализ HTML с помощью регулярных выражений обычно плохая идея .

Ответы [ 3 ]

2 голосов
/ 23 февраля 2012

Если файл HTML, который вы анализируете, имеет известную фиксированную структуру, вы можете использовать awk для этого. Нетрудно написать программу, которая сохраняет состояние в переменной (например, ожидает заголовок, анализирует заголовок, ожидает тело) и выполняет разные действия при чтении файла. Он также поддерживает регулярные выражения, и вы можете поместить все в хорошо структурированный файл.

1 голос
/ 23 февраля 2012

Вы можете использовать параметр -H (HTML), предоставляемый командой xmlstarlet, для управления файлом HTML.

Например:

# content of template file
$ cat template.html
<!DOCTYPE html >
<html lang="en">
    <head> ... </head>
    <body>
        <div id="div1"></div>
        <div id="div2"></div>
    </body>
</html>

# update the head tag
$ xmlstarlet ed -H -u '//head' -v 'hello, world' template.html
<?xml version="1.0"?>
<!DOCTYPE html>
<html lang="en">
  <head>hello, world</head>
  <body>
    <div id="div1"/>
    <div id="div2"/>
  </body>
</html>
0 голосов
/ 23 февраля 2012

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

...