Что нового

Как организовать комплексное удаление тегов и ненужной инфы?

hellm

Новичок
Сообщения
32
Репутация
1
Задался вот идеей подчищать html-файлы, оставляя полезную инфу. Что касается обычных способов убирания мусора, то проблем нет. Вот регами никак не разобраться.

К примеру текст:
Код:
<style ...> aaabbb </style>
<script...> aaabbb </script>

Все это счастье мне с содержимым не нать, зато:

Код:
<p> aaabbb
<i> ddd </i>

здесь не нужны только теги, а содержание должно остаться.

Текст находится внутри тега <body>. Пробовал вытянуть его (текст) через _IEBodyReadHTML, но увы, неудача. Теперь хочу попробовать регулярные выражени. Но сколько о них не бился(даже PCRE Toolkit установил) так и не разобрался.
Помогите. Как правильно прописать эти выражения для моей задачи?
 

sngr

AutoIT Гуру
Сообщения
1,010
Репутация
408
Чтобы удалить теги рег выражения не нужны.
Код:
$str='<i> ddd </i>'
MsgBox(32,'',StringReplace(StringReplace($str,'</i>',''),'<i>',''))
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
hellm
Поиск рулит
http://autoit-script.ru/index.php/topic,10844.msg71578.html#msg71578
 
Автор
H

hellm

Новичок
Сообщения
32
Репутация
1
sngr [?]
Чтобы удалить теги рег выражения не нужны.

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

AZJIO [?]

Спасибо, что напомнили про поиск, я ничего не нашел. Но ведь не зря создал новую тему!
Ваш скрипт попробовал, он не вырезает все теги. Надо ли его настраивать?
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
hellm [?]
он не вырезает все теги. Надо ли его настраивать?
Надеялся на самостоятельные попытки.
Код:
$sText='<tag class=syper>ds'
$sText=StringRegExpReplace($sText, '</?\w+((\s+\w+(\s*=\s*(?:".*?"|''.*?''|[^''">\s]+))?)+\s*|\s*)/?>', '')
MsgBox(0, 'Сообщение', $sText)

Шаблон взял из RegExp
 
Автор
H

hellm

Новичок
Сообщения
32
Репутация
1
Так, правильно ли я понял(??? - не понял):

Код:
<    --- начало тега

Код:
/?    --- ???

Код:
\w+ --- слово длиной мин. в 1 символ

Код:
\s+\w+  --- миниму 1 пробел (включая различные табуляции, далее просто пробел) и слово длиной мин. в 1 символ

Код:
?:".*?"|''.*?''|  ---  ???

Код:
[^''">\s]+  ---  не ищет символы в квадратных скобках длиной мин. в 1 символ
Код:
(\s*=\s*)?)+  ---  это, видимо, выражение, пробел(\s) от 0(*) и более раз равно опять пробел от 0 и более раз, все 
это может быть, а может нет (знак вопроса) и от 1го и более раз (+)
Код:
\s*|\s*)  --- ??? (пробел >= 1го раза или пробел >= 1го раза ------ как это понимать)

Код:
/?  ---  ???

Код:
>   --- конец тега

Почему такая расстановка круглых скобок?
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
hellm
Есть справка по регулярным выражениям. Там как раз я добавил новый раздел по регулярным выражениям с описанием работы с группами.
/? означает повторить предыдущий символ 0 или 1 раз. Это написано в справке
(...)? тоже самое, группа либо есть либо нет (0 или 1 раз).
?:".*?"|''.*?''| перечисление или ".*?" или '.*?'
?: группа без вывода в результат, без сохранения, без ссылки.
[^''">\s]+ ищет все символы кроме указанных, кроме " ' > и пробельных

Ну всё это написано в справке.

\s*|\s*) --- ??? (пробел >= 1го раза или пробел >= 1го раза ------ как это понимать)
если не выдирать из контекста то легко понимать в первом случай какой то текст заканчивающийся пробелами или просто пробелы. Я ж не не стал бы писать s*|\s*) или так *|\s*) это же разные записи. Скобка определяет группу перечислений. Найди пару для этой скобки и всё что от неё, то и будет в левой половине.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Я пользуюсь такой регуляркой
Код:
(?i)<(style|script)[^<>]*>.*?</\1>|</?[a-z][a-z0-9]*[^<>]*>|<!--.*?-->
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
hellm
Задача всё ещё не будет решена, преобразование символов ещё надо сделать.

Код:
; Преобразуем данные в правильный текст без &lt; и тому подобных
#include <Array.au3>

$filehtm = @ScriptDir & '\index.htm'

If Not FileExists($filehtm) Then
	MsgBox(0, 'Сообщение', 'Требуется файл htm, указываем в скрипте')
	Exit
EndIf
$text = FileRead($filehtm)

$log = ''


; Замена некоторых часто испольхуемых спецсимволов, а их на самом деле больше
$text = StringRegExpReplace($text, '&quot;', '"')
If Not @error Then $log &= @extended & '   quot' & @CRLF

$text = StringRegExpReplace($text, '&amp;', '&')
If Not @error Then $log &= @extended & '   amp;' & @CRLF

$text = StringRegExpReplace($text, '&lt;', '<')
If Not @error Then $log &= @extended & '   lt' & @CRLF

$text = StringRegExpReplace($text, '&gt;', '>')
If Not @error Then $log &= @extended & '   gt' & @CRLF

$text = StringRegExpReplace($text, ' ', ' ')
If Not @error Then $log &= @extended & '   nbsp' & @CRLF

$text = StringRegExpReplace($text, '&iexcl;', '¡')
If Not @error Then $log &= @extended & '   iexcl' & @CRLF

$text = StringRegExpReplace($text, '&cent;', '¢')
If Not @error Then $log &= @extended & '   cent' & @CRLF

$text = StringRegExpReplace($text, '&pound;', '£')
If Not @error Then $log &= @extended & '   pound' & @CRLF

$text = StringRegExpReplace($text, '&copy;', '©')
If Not @error Then $log &= @extended & '   copy' & @CRLF

; Замена знаков юникода выраженных числовым кодом
$a = StringRegExp($text, '&#(\d+);', 3)
If Not @error Then
	$log &= UBound($a) & '   &#(\d+);' & @CRLF
	$a = _ArrayUnique($a)
	For $i = 1 To $a[0]
		$a[$i] = Number($a[$i])
	Next
	_ArraySort($a, 1, 1) ; чтобы не испортить к примеру число 853 числом 85
	; _ArrayDisplay($a, "Массив после сортировки по убыванию")
	For $i = 1 To $a[0]
		$text = StringReplace($text, '&#' & $a[$i] & ';', ChrW($a[$i]))
	Next
EndIf


; i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!

; блок исправлений текущей реализации. Если файл в UTF8 то в нём могут быть юникодные символы, которые при сохранении а ASCI будут испорчены
$text = StringRegExpReplace($text, '[“”]', '"') ; неправильные кавычки
If Not @error Then $log &= @extended & '   кавычки “ ”' & @CRLF

$text = StringReplace($text, ChrW(160), ' ') ; заменить пробел 160 на пробел 32
If @extended Then $log &= @extended & '   пробел' & @CRLF

$text = StringReplace($text, ChrW(8226), '') ; удалить кругляшок
If @extended Then $log &= @extended & '   о > ' & @CRLF

$text = StringReplace($text, ChrW(8211), '-') ; длинное тире на правильный минус
If @extended Then $log &= @extended & '   - > -' & @CRLF

$text = StringReplace($text, ChrW(8230), '...') ; троеточие на три точки
If @extended Then $log &= @extended & '   ...' & @CRLF

$text = StringReplace($text, ChrW(8212), '-') ; очень длинное тире на короткое
If @extended Then $log &= @extended & '   - > -' & @CRLF

; i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!

; Сохранение в другой файл
$file = FileOpen(@ScriptDir & '\index2.htm', 2)
FileWrite($file, $text)
FileClose($file)

; Сохранение отчёта чтобы увидеть количество замен и найденных символов
$file = FileOpen(@ScriptDir & '\log.txt', 2)
FileWrite($file, $log)
FileClose($file)

MsgBox(0, 'Готово', 'Конвертация HTML-символов в текст')
Хотя возможно и этим дело не закончится. Всегда найдётся код который не будет соответствовать правилам. Написать очередной "ВебЛомастер" не так уж легко.
 
Автор
H

hellm

Новичок
Сообщения
32
Репутация
1
AZJIO [?]
Ну всё это написано в справке.

не сомневаюсь ни на минуту, просто хотел уточнить, правильно ли я понял написанное, спасибо за ответ

Задача всё ещё не будет решена, преобразование символов ещё надо сделать.

А вот об этом даже не подумал. Огромное спасибо!

inververs [?]
Я пользуюсь такой регуляркой

(попробовал)
Если я правильно понимаю, то
(?i) --- в любом регистре
<(style|script)[^<>]*> --- тег style или script с любым продолжением и без <>, хотя не совсем понятно, ведь если будет стоять language=... после script например, он разве его увидит?
.*? --- от одного и более символов может и не появиться (к сожалению не удаляет текст скрипта/стиля, если он на новой строке)
</\1> --- ???
|</?[a-z][a-z0-9]*[^<>]*> --- или нижним регистром или нижним и цифрами от 1го и более раз без <>, но может и не появиться
|<!--.*?--> --- или коменты

Кстати, на счет переноса строки видел статью (источник на этом сайте, но я его не нашел), чтобы учесть перенос стоки, надо поставить перед выражением (?s). С Вашим регом очень хорошо сработало (правда, осталось много пустых строк ;D)
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
hellm
.*? --- от одного и более символов может и не появиться (к сожалению не удаляет текст скрипта/стиля, если он на новой строке)
добавь s, так (?is)

ведь если будет стоять language=... после script например, он разве его увидит?
[^<>]* эта штука захватит всё и language= тоже
</\1> ссылка на группу, то есть если нашла script то он должен завершится тегом script, а не style. Они как раз заключены в группу чтобы сделать выбор и ссылку на группу.
|</?[a-z][a-z0-9]*[^<>]*> немного странноватое, в принципе соединять [a-z0-9]* с [^<>]* бессмысленно, так как если первое не совпало то сработает второе, а второе включает в себя и первое так что запись |</?[a-z][^<>]*> будет работать одинаково. Неужели первое всегда буква? Я бы не парился и сделал бы так </?[^<>]+>, то есть любой тег или <.+?>.
 
Автор
H

hellm

Новичок
Сообщения
32
Репутация
1
inververs [?]
Я пользуюсь такой регуляркой

Почему [^<>]* само по себе не работает?
Более того, зачем нужно включать цифры/буквы в центре выражения |</?[a-z][a-z0-9]*[^<>]*> ??? Единственное знаю, что без них не работает. :smile:
Зачем это выражение нужно |</?[a-z][a-z0-9]*[^<>]*>, ведь мы написали </\1> ??? Получается, что может быть и другие окончания ???
Как этот скрипт видит ВСЕ теги, если он только под script/style заточен ???
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
hellm
вот эта палочка | означает или, поэтому тут 3 выражения. 1 -ое удаляет скрипты и стили, 2 - удаляет тэги, 3 - удаляет комментарии
 
Автор
H

hellm

Новичок
Сообщения
32
Репутация
1
А я-то был уверен, что они связаны!
Спасибо.
 
Верх