#html #regex #vi
#HTML #регулярное выражение #vi
Вопрос:
Бывали случаи, когда мне нужно было «преобразовать» старую структуру HTML в новую. Чтобы проиллюстрировать, преобразование этого:
<!-- Old HTML structure. -->
<div class="class-a">
<div class="class-b">
<span>Hello</span>
</div>
<div class="class-c">
<p>How are you doing?</p>
</div>
</div>
<div class="class-a">
<div class="class-b">
... (and so on, basically repeats the construct above) ...
К чему-то вроде:
<!-- New HTML structure. -->
<div class="class-aa">
<span class="class-ab">Hello</span>
<p>How are you doing?</p>
</div>
<div class="class-aa">
<span class="class-ab">Hi!</span>
... (and so on, basically repeats the construct above) ...
Обратите внимание, что мне все еще нужен текст, но структура нуждается в полном пересмотре.
Худшая ситуация заключается в том, что HTML-файл очень длинный и выполняется вручную (да, много ввода). То, что я делал до сих пор, — это либо использование простого регулярного выражения подстановки (если оно не слишком сложное), либо обращение к старому школьному макросу vi.
Кто-нибудь, пожалуйста, предложит лучший подход для достижения этой цели?
Комментарии:
1. Можете ли вы точно определить изменения, которые вы хотите внести? (Если нет, то как вы ожидаете «объяснить» их любому инструменту, который их выполнит? Если да, давайте послушаем подробности, чтобы мы могли помочь вам лучше.)
2. @Tom: Простой пример выше отражает то, что я пытался сделать. Пожалуйста, посмотрите на комментарий RoToRa ниже. Спасибо.
Ответ №1:
Вы могли бы написать JavaScript / jQuery, который выполняет реструктуризацию, а затем с помощью инспектора / отладчика DOM браузера получить копию измененного HTML.
Кстати, некоторое время назад я искал редактор / инструмент, который автоматически выполняет подобные действия, но, похоже, такой вещи не существует: https://softwareengineering.stackexchange.com/questions/79615/html-text-editor-with-dom-manipulation
Комментарии:
1. Это довольно умно, вы также можете манипулировать dom с помощью php или python (и некоторых других) с их встроенными библиотеками. Если у вас больше файлов, я думаю, это было бы проще сделать.
Ответ №2:
Похоже, вы хотите манипулировать структурой (вы, кажется, симпатизируете «DOM») HTML, а не текстом. И вы хотите сделать это, потому что, нормализуя HTML в структуру, подобную DOM, вы избавляетесь от проблем с разметкой текста, HTML-тегами, написанными в смешном регистре, наличием / отсутствием атрибутов и т. Д.
Вероятно, это не так удобно, как хотелось бы, но система преобразования программы из источника в исходный код может помочь.
Такой инструмент анализирует текст языка (в вашем случае HTML) и создает AST, структуру данных, несколько похожую на DOM, поскольку она фиксирует точную структуру кода, например, теги, их вложенность и прикрепленные атрибуты и текст. После того, как вы получили AST, вы можете применить преобразования к AST, используя синтаксис поверхности HTML, который вы знаете и любите (?). Преобразования работают со структурой, а не с текстом, поэтому у вас не будет проблем с текстом. После преобразования вы восстанавливаете текст на языке (HTML) из исправленного AST.
Наш инструментарий для реинжиниринга программного обеспечения DMS является одним из таких инструментов. Вы могли бы записать желаемое изменение выше как преобразование:
domain HTML;
rule revise_div(t1: text, t2:text):div_tag->div_tag =
"<div class="class-a">
<div class="class-b">
<span>t1</span>
</div>
<div class="class-c">
<p>t2</p>
</div>
</div>"
->
"<div class="class-aa">
<span class="class-ab">t1</span>
<p>t2</p>
</div>";
Это правило перезаписи состоит из трех частей: заголовок, содержащий имя правила, и объявления параметров, которые указывают, какие типы заполнителей будут привязаны к телу правила, шаблон сопоставления с левой стороны (внутри кавычек) и шаблон замены с правой стороны (после ->) также внутри кавычек. Кавычки не являются кавычками HTML; это синтаксис перезаписи правил «metaquotes», которые отделяют синтаксис HTML от синтаксиса правила преобразования.
Параметры в этом случае предназначены для представления двух текстовых строк t1 и t1; они находятся внутри шаблонов как t1 и t2, при этом является метаэскейпом правила перезаписи, поскольку эти имена параметров не являются частью html, а просто представляют найденный там текст.
Механизм перезаписи, учитывая это правило, сопоставит точку в AST (или все точки, в зависимости от того, как вы ее вызываете), свяжет t1 и t2 с соответствующими строками, удалит сопоставленное поддерево (HTML в шаблоне сопоставления) и заменит его шаблоном правой части сзаменены соответствующие значения t1 и t2.
Если ваш HTML действительно регулярный в использовании, это будет очень удобно. Вы можете запрограммировать эти правила и применять их повторно ко многим файлам. Вы сможете написать несколько правил, которые охватывают варианты. Я бы немного беспокоился о том, что большая часть HTML написана случайным программистом на данный момент, и они не согласуются с тем, что они делают, и никакой фиксированный набор правил не решит вашу проблему.
Ответ №3:
Хм … не могли бы вы просто сделать замену?
<div class="class-a">
<div class="class-b">
<span>
становится
<div class="class-aa">
<span class="class-ab">
и
</span>
</div>
<div class="class-c">
<p>
становится
</span>
<p>
наконец,
</p>
</div>
</div>
превращается в
</p>
</div>
Если ваш документ действительно имеет одну и ту же структуру снова и снова, вы должны быть в состоянии сделать это с помощью этих трех команд find replace . Проще, чем написать скрипт или вычислить регулярное выражение.
Комментарии:
1. Это определенно выполнимо, когда структура не слишком сложна; приведенные выше фрагменты приведены только для иллюстрации. На практике целевой HTML-файл может не иметь такого точного интервала, заглавных букв и т. Д. чтобы всегда соответствовать критериям поиска и замены.
2. Правильно, тогда вы привязаны к более сложному решению… Всегда ли структура текста одинакова? Т.Е. это всегда заголовок-заголовок-комментарий или что-то в этом роде? В этом случае вы могли бы удалить теги, поместить реальное содержимое в массив и заполнить свой новый html-код, выполняя цикл по массиву.