Про видалення тегів
Олег Алістратов, www.ali.com.uaДивно багато міфів володіє умами людства. Стародавні сушили Балду над завданнями про подвоєння куба і трисекції кута. Пізніше увійшли в моду пошуки філософського каменю та відбирання у сарацинів гробу Господнього. У новий час займалися дослідженням флогістону, ефіру і мавпячих залоз. Досить довго намагалися вирішити проблему встановлення щастя для всіх - в одному окремо взятій державі. З появою веб-технологій у людей знайшлася нова брязкальце - видалення тегів.
Як відомо, документ на HTML складається з двох речей: тексту як такого і тегів, які задають його структуру. Мухи окремо, котлети окремо. Теги використовуються також для оформлення тексту, і цим часто зловживають новачки, змушуючи обурюватися суворих іменитих дизайнерів. Але які теги використовувати, скільки і яким чином - особиста справа кожного. І поки це залишається вашим особистим ділом, усе в порядку.
Але от веб-майстер побажав мати на своєму сайті чат або форум. Або, хто попроще, гостьову книгу. Або, хто серйозніше, сторінку зворотнього зв'язку. Суть в тому, що він тепер не розпоряджається одноосібно наповненням контенту свого сайту - контент, більшою чи меншою мірою, формують відвідувачі.
Відвідувач ж має шкідливу схильність писати в поля форм всілякі дурниці. Просто так дурницю писати він не буде - тільки час даремно витрачати. Якщо ж відвідувач технічно грамотний і тяжіє до хуліганства - спритно орудуючи цими самими тегами і java-скриптами, він буде набивати вашу гостьову книгу (або що ви там поставили) сороміцькі написами та малюнками. Шкідливі теги з повідомлень відвідувачів слід видаляти, залишаючи тільки кристально чистий текст.
Тому ньюс-групи та ехоконференції повні листами під топікамі "Як прибрати теги ??!!". Зміст їх завжди однаково, відрізняються вони лише кількістю знаків питання у заголовку. Листи ці породжують масу відповідей з очевидним рішенням - прибрати все від лівої кутової дужки до наступної за нею правою, благо в HTML заборонені конструкції виду
<TagA ... <tagB> ...>
(Втім, брешу, можливо <! - <img...> ->
таке), і тоді регексп (регулярний вираз, regular exdivssion) s /<([^>]| \ n )*>// g
спрацює належним чином. Проте знавці HTML одразу б'ють потужним аргументом: <input type="submit" value="Next>>> ">
Ясно, що цей абсолютно правильний з точки зору HTML тег описана процедура видалить тільки частково, залишивши незрозумілий сміття. Корифеї призводять наступного монстра регулярних виразів: s / <[A-za-z ]([^'">]*['"][^'"]*?['"])*[^>]*>// sig
Щоправда, і в цьому випадку залишаються проблеми. Але регекспи взагалі, а особливо ті, що складніше заміни однієї літери на іншу, бентежать початківців програмістів. Не знаючи суті, легко допустити помилку. Але справа не в цьому ... Відволічемося від регулярних виразів, і подивимося на проблему уважно. "Ми повинні розуміти всю глибину наших глибин © Дикий прапор, ДМБ". Чи треба взагалі видаляти теги? А якщо цю статтю, яку ви читаєте, хто-то хоче опублікувати на форумі? Я так ретельно відбирав ці приклади, так довго підбирав цей синьо-зелененький колір ... Прикро буде відправити їх до індіанського Маніту, в / dev / null, або куди там відправляються вирізані регекспамі частини тексту.
Двох секунд роздуми веб-майстру достатньо, щоб переконатися: у більшості випадків теги потрібно не видаляти, а показувати. Досягти цього просто: необхідно замінити у вихідному тексті символи, використовувані в тегах, на відповідні підстановки-"ентіті" (entities). Видаляти ж теги потрібно у разі перетворення HTML у звичайний текст, і для цього краще скористатися відповідними бібліотеками (наприклад, модулем HTML:: Parser для Перла).
Однак і з "Ентіті" не все так просто. Основне питання - коли здійснювати підстановку. Перед збереженням даних на сервері або перед формуванням сторінки, і важливо не зробити це двічі. До тих пір, поки я серйозно задумався над цим питанням (адже все здавалося так елементарно! ... Воно і є елементарно, але потрібна акуратність), повна неузгодженість в обробці тегів скриптами приводила до того, що теги з'являлися де не потрібно, зникали там , де потрібні, а лапки і амперсанд перетворювалися на щось незрозуміле. Якщо дані віддавалися для повторного редагування у форму, переклади рядків повинні залишатися на своїх місцях, а на форумі їх краще замінити на тег
. Загалом, варто було тільки трохи подумати. Через п'ять хвилин з'явилася методика, яка більше мене ніколи не підводила. Ось вона:
1. Всі дані, введені відвідувачем, залишати без змін і "як є" заносити їх в базу даних або в файл.
2. Так їх і зберігати.
3. Перетворювати їх лише перед виведенням на сторінку. Для цього замінюємо спочатку амперсанд, а потім лапки і кутові дужки на "ентіті".
4. Якщо не виводимо в полі типу textarea, додатково замінюємо переклади рядків на тег <br>.
Все. Ось функція заміни на Перлі:
sub html_chars
{
my ($ r, $ br) = @ _;
$ R = ~ s /&/&/ gs;
$ R = ~ s /"/"/ gs;
$ R = ~ s /</</ gs;
$ R = ~ s />/>/ gs;
$ R = ~ s / \ n / <br> / gs if $ br;
return $ r;
}
Вона приймає два параметри: обов'язковий - текст (скаляр), що підлягає перетворенню, і необов'язковий прапорець (будь-якого типу, ненульовий і непорожній), що показує, чи робити перетворення перекладів рядків. Отже, я раджу вам визначитися - чи збираєтеся ви видаляти теги в надісланих даних. Якщо ні, то розберіться раз і назавжди, як і коли пригнічувати їх перед виведенням сторінки користувачеві. І тоді ви просвітліє виглядом і наповніть своє життя сенсом ще на 18 відсотків ...
Щиро Ваш,
Олег Алістратов, Aiken WDS.