Інтернет Windows Android

Очищення тексту від зайвих html-тегів - Парсинг від А до Я. Видалення з рядка HTML тегів в PHP Php прибрати html теги з рядка

Із завданням очищення html від зайвих тегів стикаються абсолютно всі.

Перше, що спадає на думку, це використовувати php-функцію strip_tags ():
string strip_tags (string str [, string allowable_tags])

Функція повертає рядок, очищену від тегів. Як аргумент allowable_tags передаються теги, які не треба видаляти. Функція працює, але, м'яко кажучи, неідеально. По ходу, там немає перевірки на валідність коду, що може спричинити за собою видалення тексту, що не входить в теги.
Ініціативні розробники склавши руки не сиділи - в мережі можна знайти допрацьовані функції. Хорошим прикладом є strip_tags_smart.

Застосовувати чи не застосовувати готові рішення - особистий вибір програміста. Так склалося, що мені частіше за все не потрібно "універсального" обробника і буває зручніше почистити код регулярки.

Від чого залежить вибір того чи іншого способу обробки?

1. Від вихідного матеріалу і складності його аналізу.
Якщо вам потрібно обробляти досить прості htmp-тексти, без будь-якої навороченной верстки, ясні, як день :), то можна використовувати стандартні функції.
Якщо в текстах є певні особливості, які треба врахувати, то тут-то і пишуться спеціальні обробники. В одних може використовуватися просто str_replace. наприклад:

$ S \u003d array ( "â € ™" \u003d\u003e " '", // Right-apostrophe (eg in I "m)
" € œ" \u003d\u003e "" ", // Opening speech mark
"Â €" "\u003d\u003e" - ", // Long dash
"Â €" \u003d\u003e "" ", // Closing speech mark
"Ã" \u003d\u003e "é", // e acute accent
chr (226). chr (128). chr (153) \u003d\u003e " '", // Right-apostrophe again
chr (226). chr (128). chr (147) \u003d\u003e "-", // Long dash again
chr (226). chr (128). chr (156) \u003d\u003e "" ", // Opening speech mark
chr (226). chr (128). chr (148) \u003d\u003e "-", // M dash again
chr (226). chr (128) \u003d\u003e "" ", // Right speech mark
chr (195). chr (169) \u003d\u003e "é", // e acute again
);

foreach ($ s as $ needle \u003d\u003e $ replace)
{
$ HtmlText \u003d str_replace ($ needle, $ replace, $ htmlText);
}

Інші можуть бути засновані на регулярних виразах. Як приклад:

Function getTextFromHTML ($ htmlText)
{
$ Search \u003d array ( ""]*?>.*?"Si", // Remove javaScript
""]*?>.*?"Si", // Remove styles
""]*?>.*?"Si", // Remove xml tags
""<[\/\!]*?[^<>] *?\u003e "Si", // Remove HTML-tags
"" ([\\ R \\ n]) [\\ s] "", // Remove spaces
"" & (Quot | # 34); "i", // Replace HTML special chars
"" & (Amp | # 38); "i",
"" & (Lt | # 60); "i",
"" & (Gt | # 62); "i",
"" & (Nbsp | # 160); "i",
"" & (Iexcl | # 161); "i",
"" & (Cent | # 162); "i",
"" & (Pound | # 163); "i",
"" & (Copy | # 169); "i",
"" (\\ D); "e"); // write as php

$ Replace \u003d array ( "",
"",
"",
"",
"\\1",
"\"",
"&",
"<",
">",
" ",
chr (161),
chr (162),
chr (163),
chr (169),
"Chr (\\\\ 1)");

Return preg_replace ($ search, $ replace, $ htmlText);
}
(В такі хвилини як ніколи радує можливість preg_replace працювати з масивами в якості параметрів). Масив ви при необхідності доповнюєте своїми регулярки. Допомогти в їх складанні вам може, наприклад, цей конструктор регулярних виразів. Початківцям розробникам може бути корисною стаття "All about HTML tags. 9 Regular Expressions to strip HTML tags". Подивіться там приклади, проаналізуйте логіку.

2. Від обсягів.
Обсяги безпосередньо пов'язані зі складністю аналізу (з попереднього пункту). Велика кількість текстів збільшує ймовірність, що, намагаючись передбачити і почистити всі регулярки, ви можете що-небудь та упустити. У цьому випадку підійде метод "багатоступінчастої" очищення. Тобто очистити спочатку, припустимо, функцією strip_tags_smart (исходники про всяк випадок не видаляємо). Потім вибірково переглядаємо кілька текстів на виявлення "аномалій". Ну і "зачищаємо" аномалії регулярки.

3. Від того, що треба отримати в результаті.
Алгоритм обробки може бути спрощений різними способами в залежності від ситуації. Випадок, описаний мною в одній з попередніх статей, добре це демонструє. Нагадаю, текст там знаходився в div-е, в якому крім нього був ще div з "хлібними крихтами", реклама адсенс, список схожих статей. При аналізі вибірки статей виявилося, що статті не містять малюнків і просто розбиті на абзаци за допомогою. Щоб не чистити "головний" див від сторонніх речей, можна знайти все абзаци (з Simple HTML DOM Parser це дуже просто) і з'єднати їх вміст. Так що перш ніж складати регулярки для чищення, подивіться, чи не можна обійтися малою кров'ю.

Взагалі, між прихильниками парсинга html-коду, заснованого чисто на регулярних виразах, і парсинга, в основі якого лежить аналіз DOM-структури документа, в мережі розпалюються справжні холівари. Ось, наприклад, на оверфлоу. Невинний з першого погляду

Перевірка і обробка вхідних даних є однією з поширених завдань в програмуванні. Мова PHP зазвичай використовується для веб-додатків, тому тут найбільш актуально видалення HTML тегів з тексту, адже саме вони найбільш наражені стороннім ін'єкцій. У даній статті я хочу нагадати Вам про старичка stip_tags () і його фішках, а також запропонувати рішення для видалення секційних HTML тегів і ще парочку корисних бонусів навздогін.

І так. Основним нашим інструментом для видалення HTML тегів з тексту є функція strip_tags (). Ми передаємо їй строкове значення, а вона видаляє з нього HTML і PHP теги, наприклад:

$ S \u003d "

Параграф.

Ще текст. ";
echo strip_tags ($ s);

Цей приклад виведе рядок:

Параграф. Ще текст.

Примітно тут те, що у функції є і другий (Не обов'язково, але корисний) параметр, значенням якого є рядок з переліком дозволених HTML тегів, наприклад:

$ S \u003d "

Параграф.

Ще текст. ";
echo strip_tags ($ s, "

Цей приклад виведе рядок:

Параграф.

Ще текст.

На мою думку, дуже зручно. Тим не менш, це не вирішує одну важливу проблему - видалення секційних HTML тегів, Наприклад: script, noscript і style - вони найбільш поширені. Коли мені потрібно прибрати такі секційні теги, а також варіанти починаються з «< » и заканчивающиеся символом « > », Я використовую наступний PHP код:

$ P \u003d array (
""]*?>.*?"Si",
""]*?>.*?"Si",
""]*?>.*?"Si",
""<[\/\!]*?[^<>] *?\u003e "Si",
);
$ R \u003d array ( "", "", "", "");
$ S \u003d preg_replace ($ p, $ r, $ s);

Тут змінна $ p містить масив регулярних виразів, а $ r - масив відповідної їх заміни (Я використовую прогалини). Залишилося лише провести заміну в рядку, і ми приберемо HTML сміття з тексту.

Очевидно, що два вище наведених рішення можна поєднати. На початку я використовую заміну через регулярні вирази, а потім strip_tags () і у мене виходить своя функція nohtml ().

Наостанок хочу запропонувати Вам ще декілька корисних рішень. Так в тексті краще замінити табуляцію прогалиною, результат інтерпретації того і іншого в браузері ідентичні, а клопоту буде менше, наприклад:

$ S \u003d str_replace ( "\\ t", "", $ s);

Якщо Вам не потрібні переноси рядків, їх теж можна замінити пробілами, наприклад:

$ S \u003d str_replace (array ( "\\ n", "\\ r"), "", $ s);

Від зайвих ж прогалин можна позбутися простим регулярним виразом, наприклад:

$ S \u003d preg_replace ( "/ \\ s + /", "", $ s);
$ S \u003d trim ($ s); // буде не зайвим

На цьому у мене все. Дякуємо за увагу. Успіхів!

о 21:56 змінити повідомлення

У Вас в браузері заблокований JavaScript. Дозвольте JavaScript для роботи сайту!

strip_tags

(PHP 3\u003e \u003d 3.0.8, PHP 4, PHP 5)

strip_tags - Видаляє HTML і PHP теги з рядка

опис

string strip_tags (String str [, string allowable_tags])

Ця функція повертає рядок str, з якої вилучені HTML і PHP теги. Для видалення тегів використовується автомат, аналогічний застосованому в функції fgetss ().

Необов'язковий другий аргумент може бути використаний для вказівки тегів, які не повинні видалятися.

зауваження: Аргумент allowable_tags був доданий в PHP 3.0.13 і PHP 4.0b3. З версії PHP 4.3.0 видаляються також HTML коментарі.

Увага

Так як strip_tags () не перевіряє коректність HTML коду, незавершені теги можу привести до видалення тексту, що не входить в теги.

Приклад 1. Приклад використання strip_tags ()
$ Text \u003d "

Параграф.

Ще трохи тексту "; echo strip_tags ($ text); echo" \\ n \\ n ------- \\ n "; // не видаляти

Echo strip_tags ($ text, "

"); // Дозволяємо ,, echo strip_tags ($ text, " ");

Цей приклад виведе:

Параграф. Ще трохи тексту -------

Параграф.

Ще трохи тексту

Увага

Ця функція не змінює атрибути тегів, зазначених в аргументі allowable_tags, включаючи style і onmouseover.

З версії PHP 5.0.0 strip_tags () безпечна для обробки даних в двійковій формі.

У цієї функції є істотний недолік - це склейка слів при видаленні тегів. Крім цього функція має уразливості. Альтернативна функція аналог strip_tags:

c "* - коректно обробляється" брудний "html, коли в значеннях атрибутів тегів можуть зустрічатися символи< > * - коректно обробляється розбитий html * - вирізаються коментарі, скрипти, стилі, PHP, Perl, ASP код, MS Word таги, CDATA * - автоматично форматується текст, якщо він містить html код * - захист від підробок типу: "<script\u003e alert ( "hi")script\u003e "* * @param string $ s * @param array $ allowable_tags Масив тагов, які не будуть вирізані * Приклад:" b "- таг залишиться з атрибутами," "- таг залишиться без атрибутів * @param bool $ is_format_spaces Форматувати прогалини і переноси рядків? * Вид тексту на виході (plain) максимально прібліжеется увазі тексту в браузері на вході. * Іншими словами, грамотно перетворює text / html в text / plain. * Текст форматується тільки в тому випадку, якщо були вирізані будь-які теги. * @param array $ pair_tags масив імен парних тегів, які будуть видалені разом з вмістом * см. значення за замовчуванням * @param array $ para_tags масив імен парних тегів, які будуть сприйматися як параграфи (якщо $ is_format_spaces \u003d true) * см. значення за замовчуванням * @return string * * @license http://creativecommons.org/licenses/by-sa/3.0/ * @author Nasibullin Rinat, http: //orangetie.ru/ * @charset ANSI * @version 4.0.14 * / function strip_tags_smart (/ * string * / $ s, array $ allowable_tags \u003d , / * boolean * / $ is_format_spaces \u003d true, array $ pair_tags \u003d array ( "script", "style", "map", "iframe", "frameset", "object", "applet", "co mment "," button "," textarea "," select "), array $ para_tags \u003d array (" p "," td "," th "," li "," h1 "," h2 "," h3 ", "h4", "h5", "h6", "div", "form", "title", "pre")) (// return strip_tags ($ s); static $ _callback_type \u003d false; static $ _allowable_tags \u003d array (); static $ _para_tags \u003d array (); #regular expression for tag attributes #correct processes dirty and broken HTML in a singlebyte or multibyte UTF-8 charset! static $ re_attrs_fast_safe \u003d "(?!) #statement, which follows after a tag #correct attributes (?\u003e [^\u003e" \\ "] + | (?<=[\=\x20\r\n\t]|\xc2\xa0) "[^"]*" | (?<=[\=\x20\r\n\t]|\xc2\xa0) \"[^\"]*\")* #incorrect attributes [^>] * + "; If (is_array ($ s)) (if ($ _callback_type \u003d\u003d\u003d" strip_tags ") ($ tag \u003d strtolower ($ s); if ($ _allowable_tags) (#tag with attributes if (array_key_exists ($ tag, $ _allowable_tags)) return $ s; #tag without attributes if (array_key_exists ( "<" . $tag . ">", $ _Allowable_tags)) (if (substr ($ s, 0, 2) \u003d\u003d\u003d""; If (substr ($ s, -2) \u003d\u003d\u003d" /\u003e ") return"<" . $tag . " />"; Return"<" . $tag . ">";)) If ($ tag \u003d\u003d\u003d" br ") return" \\ r \\ n "; if ($ _para_tags && array_key_exists ($ tag, $ _para_tags)) return" \\ r \\ n \\ r \\ n "; return "";) trigger_error ( "Unknown callback type" ". $ _callback_type." "!", E_USER_ERROR);) if (($ pos \u003d strpos ($ s, "<")) === false || strpos($s, ">", $ Pos) \u003d\u003d\u003d false) #speed improve (#tags are not found return $ s;) $ length \u003d strlen ($ s); #unpaired tags (opening, closing,! DOCTYPE, MS Word namespace) $ re_tags \u003d "~: * +)?) # 1 ". $ Re_attrs_fast_safe."\u003e ~ SxSX "; $ patterns \u003d array (" /<([\?\%]) .*? \\1>/ SxSX ", # вбудований PHP, Perl, ASP код" /<\!\\]>/ SxSX ", # блоки CDATA #" /<\!\[ [\x20\r\n\t]* .*? \]>/ SxSX ", #: DEPRECATED: MS Word таги типу... "/<\!--.*?-->/ SSX ", # коментарі #MS Word таги типу"...", # Умовне виконання коду для IE типу" HTML "# Умовне виконання коду для IE типу" HTML"# См. Http://www.tigir.com/comments.htm" /<\! (?:--)?+ \[ (?> [^ \\] "\\"] + | "[^"] * "| \\" [^ \\ "] * \\") * \\] (?: -)? +\u003e / SxSX ",); if ($ pair_tags) (# парні теги разом з вмістом: foreach ($ pair_tags as $ k \u003d\u003e $ v) $ pair_tags [$ k] \u003d preg_quote ($ v, "/"); $ patterns \u003d "/<((?i:" . implode("|", $pair_tags) . "))" . $re_attrs_fast_safe . "(? .*? <\/(?i:\\1)" . $re_attrs_fast_safe . "> / SxSX ";) #d ($ patterns); $ i \u003d 0; # захист від зациклення $ max \u003d 99; while ($ i< $max) { $s2 = preg_replace($patterns, "", $s); if (preg_last_error() !== PREG_NO_ERROR) { $i = 999; break; } if ($i == 0) { $is_html = ($s2 != $s || preg_match($re_tags, $s2)); if (preg_last_error() !== PREG_NO_ERROR) { $i = 999; break; } if ($is_html) { if ($is_format_spaces) { /* В библиотеке PCRE для PHP \s - это любой пробельный символ, а именно класс символов [\x09\x0a\x0c\x0d\x20\xa0] или, по другому, [\t\n\f\r \xa0] Если \s используется с модификатором /u, то \s трактуется как [\x09\x0a\x0c\x0d\x20] Браузер не делает различия между пробельными символами, друг за другом подряд идущие символы воспринимаются как один */ #$s2 = str_replace(array("\r", "\n", "\t"), " ", $s2); #$s2 = strtr($s2, "\x09\x0a\x0c\x0d", " "); $s2 = preg_replace("/ [\x09\x0a\x0c\x0d]++ | <((?i:pre|textarea))" . $re_attrs_fast_safe . "(? .+? <\/(?i:\\1)" . $re_attrs_fast_safe . "> \\ K / sxSX "," ", $ s2); if (preg_last_error ()! \u003d\u003d PREG_NO_ERROR) ($ i \u003d 999; break;)) # масив тагов, які не будуть вирізані if ($ allowable_tags) $ _allowable_tags \u003d array_flip ($ allowable_tags); # парні теги, які будуть сприйматися як параграфи if ($ para_tags) $ _para_tags \u003d array_flip ($ para_tags);)) #if #tags processing if ($ is_html) ($ _callback_type \u003d "strip_tags"; $ s2 \u003d preg_replace_callback ($ re_tags, __FUNCTION__, $ s2); $ _callback_type \u003d false; if (preg_last_error ()! \u003d\u003d PREG_NO_ERROR) ($ i \u003d 999; break;)) if ($ s \u003d\u003d\u003d $ s2) break; $ s \u003d $ s2; $ i ++;) #while if ($ i\u003e \u003d $ max) $ s \u003d strip_tags ($ s); #too many cycles for replace ... if ($ is_format_spaces && strlen ($ s)! \u003d \u003d $ length) (#remove a duplicate spaces $ s \u003d preg_replace ( "/ \\ x20 \\ x20 ++ / sSX", "", trim ($ s)); #remove a spaces before and after new lines $ s \u003d str_replace (array ( "\\ r \\ n \\ x20", "\\ x20 \\ r \\ n"), "\\ r \\ n", $ s); #replace 3 and more new lines to 2 new lines $ s \u003d preg_replace ( "/ [ \\ r \\ n] (3,) + / sSX "," \\ ) Return $ s; )?\u003e

Дивіться також опис функції

Завдання видаляти всі або тільки певні html-теги з рядка часто виникає там, де необхідно надати можливість будь-якому відвідувачу сторінки, додавати нову інформацію. Найпростішим прикладом може бути гостьова книга або система коментарів на сайті. Додається таким чином текст може містити безліч різних тегів, доданих випадково при копіюванні тексту або навмисно, щоб внести повідомлення якось "дуже оригінально". Варто відзначити також і зловмисні спроби внести на сайт шкідливий код в тегах script або спробу зіпсувати верстку сторінки зайвими тегами.

У будь-якому з перерахованих випадків, виникає необхідність перед записом нової інформації, очищати її від зайвих html-тегів.

Повне очищення тексту від html-тегів

Часто для таких завдань використовуються регулярні вирази, проте в цій статті розглянемо найпростіший метод - видалення тегів за допомогою php-функції strip_tags. Ця функція просто видаляє теги з вказаною в параметрі рядка.

$ Str_in \u003d "

Мій текст з різними тегами.

" ;
$ Str_out \u003d strip_tags ($ str_in);
echo $ str_out;

В результаті такої обробки в змінній $ str_out отримаємо рядок без тегів:

Мій текст з різними тегами.

* Варто звернути увагу, що функція strip_tags прибирає тільки самі теги, залишаючи їх вміст між відкриває і закриває тегом.

Видалення окремих html-тегів з тексту

Іноді потрібно прибрати тільки певні теги з рядка. Тут ми так само будемо використовувати функцією strip_tags, але в цей раз другим (необов'язковим) параметром вкажемо теги, які потрібно зберегти.

Наприклад, при обробці рядка, потрібно залишити тільки посилання:

$ Str_in \u003d "

Мій текст з різними тегами.

" ;
$ Str_out \u003d strip_tags ($ str_in, " " );
echo $ str_out;

В результаті такої обробки в змінній $ str_out отримаємо:

Мій текст з різними тегами.

Таким чином, можна вказати всі теги, які допустимі в рядку, тоді як всі інші будуть видалені.


У даній статті розглянуто найпростіший спосіб очищення рядки від тегів. Розглядаючи інші варіанти, я буду розширювати цю статтю. Буду радий, якщо Ви запропонуєте свої варіанти вирішення цього завдання в коментарях або по електронній пошті.