Привет, все же эта статья не о моих мыслях, а о созданном до меня творении - регулярных выраженийх, то не буду копипастить "заводские" мануалы, а сразу перейду к делу. Регулярные выраженияКак всегда, материал для затравки: http://molody.tagiltelecom.ru/doc/program/www/php4/ru/reference.pcre.pattern.syntax.html и http://www.providerz.ru/articles/php/regexp-intro.html прочитали? ну хотябы просмотрели? тогда едем дальше PHP Разберу только пшп, ибо наиболее распространен, да и в перле все точно так же) Функции, которые работают с регулярками: preg_match - http://ru2.php.net/manual/en/function.preg-match.php PHP: int preg_match( string pattern, // регулярка string subject, // строка, где ищем [, array matches] // куда поместятся результаты поиска ) Тамошний примерчик: PHP: <? function is_email($Addr) { $p = '/^[a-z0-9!#$%&*+-=?^_`{|}~]+(\.[a-z0-9!#$%&*+-=?^_`{|}~]+)*'; // имя аккаунта $p.= '@([-a-z0-9]+\.)+([a-z]{2,3}'; // зоны второго уровня $p.= '|info|arpa|aero|coop|name|museum)$/ix'; // зоны первого уровня return preg_match($p, $Addr); } ?> preg_match_all - http://ru2.php.net/manual/en/function.preg-match-all.php -аналогична простому preg_match, только эта позволяет задать порядок, в котором выводятся результаты: PHP: int preg_match_all( string pattern, // регулярка string subject, // строка, где ищем array matches // куда поместятся результаты поиска [, int order] // порядок размещения строк в результирующем массиве, принимает значения: PREG_PATERN_ORDER - нулевой элемент будет массивом полных соответствий шаблону. PREG_SET_ORDER - начиная с нулевого симовола ) Как видно, эта функция просто более удобна в некоторых ситуациях. preg_split -http://ru2.php.net/manual/en/function.preg-split.php - разбивает строку в соответствии с регулярным выражением и возвращает массив строк, как функция split() ( http://ru2.php.net/manual/en/function.split.php ): PHP: array preg_split( string pattern, // регулярка string subject, // строка, которую разбиваем [, int limit // ограничение найденных значений [, int flags] // если указать PREG_SPLIT_NO_EMPTY то функция вернет только не пустые строки ) ereg_replace - http://ru2.php.net/manual/en/function.ereg-replace.php - обрабатывает стрчоку по шаблону, например: PHP: $hash=ereg_replace("[^0-9a-fA-F]","",$hash); заменит все, что не цифра и не буква: abcdefABCDEF на пустое множество, т.е. вырежет все, кроме допустимых символов в хеше) PHP - Иной взгляд Вот другой взгляд на то же, про что и я говорил http://www.providerz.ru/articles/php/regexp-continue.html Правила хорошего тона: Комментируйте свои регулярки! ведь их наверняка нужно будет комментировать/изменять, поэтому совет: PHP: $hash=ereg_replace("[^ // все кроме 0-9 // цифры a-f // мелкие буквы abcdef A-F // большие буквы на всяк случай ABCDEF ]","",$hash); так понятнее, ведь правда? Зачем? фильтровать передаваемые скрипту значения, "сдирать" инфу с чужого сайта, да много еще как) ЗЫ: не спешите баянить, если что-то не понравилось... ИБО: не решился сразу переводить те 2 начальные статьи, ибо зачем? а щас появились сомнения. можт все же перевести на ВВ-теги форума? че сделать с теми статьями? "переварить", откомментировав каждые регулярки? ибо много где регулярки используются, а из-за отстуствия простой документации много вещей непонятны ЗЫ еще в тему: http://forum.antichat.ru/thread27498-%F0%E5%E3%F3%EB%FF%F0%ED%FB%E5.html жду камментов)
Элементарные действия Является ли строка числом, длиной до 77 цифр: PHP: if(ereg("^ // отрицание [0-9] // цифры {1,77} // квантификатор повтора предыдущего элемента (цифр) от 1 до 77 раз $",$string)) echo "yes"; else echo "no"; Состоит ли строка только из букв, цифр и "_", длиной от 5 до 20 символов: PHP: if (ereg("^ //отрицание [a-zа-я0-9_] // цифры, буквы русские, англ (строчные), и подчеркивание {5,20} // повторяются не менее 5 и не более 20 раз $",$string)) echo "yes"; else echo "no"; Есть ли в строке любые символы, кроме допустимых. Допустимыми считаются буквы, цифры и "_". Длину тут проверять нельзя, разве что просто дополнительным условием strlen($string). Не путайте с предыдущим примером - хоть результат и одинаковый, но метод другой, "от противного" PHP: if ( ! ereg("[^a-zа-я0-9_]",$string)) echo "нет посторонних букв (OK)"; else echo "есть посторонние буквы (FALSE)"; Для регистро независимого сравнения используйте eregi(). Есть ли в строке идущие подряд символы, не менее 3-х символов подряд (типа "абвгДДДеё", но не "ааббаабб"): PHP: if (preg_match("/(.)\\1\\1/",$string)) echo "yes"; else echo "no"; Заменить везде в тексте СТРОКУ1 на СТРОКУ2 (задача решается без регегулярных выражений): PHP: $string=str_replace("СТРОКА1","СТРОКА2",$string); Заменить кривые коды перехода строки на нормальные: для этого нужно только удалить "\r". Переходы бывают нормальными (но разными!): "\n" или "\r\n". Еще бывают глюки, типа "\r\r\n". PHP: $string=str_replace("\r","",$string); Заменить все повторяющиеся пробелы на один. Не пытайтесь здесь применить str_replace, это хорошая функция, но не для данного примера. PHP: $string=preg_replace("/ХХ+/","Х",$string); // вместо Х поставьте пробел В тексте есть некоторые слова, допустим "СЛОВО" и "ЛЯЛЯЛЯ" (и т.д.), которые нужно одинаковым образом заменить на тоже самое, но с добавками. Возможно, слова отсутствуют или встречаются много раз в любом регистре. Т.е. если было "слово" или "СлОвО" (или еще как), нужно заменить это на "<b>слово</b>" или "<b>СлОвО</b>" (смотря, как было). Другими словами нужно найти перечень слов в любом регистре и вставить по краям найленных слов фиксированные строки (на "<b>" и "</b>"). PHP: $string=preg_replace("/(слово1|слово2|ляляля|слово99)/si","<b>\\1</b>",$string); // то, что в скобках, заносится потом в \\1 // вертикальная черта означает или :) // остальное вроде все понятно Найти текст, заключенный в какой-то тег, например <TITLE> ... </TITLE> из HTML-файла ($string - исходный текст). PHP: //точка - все кроме пробела, ну и много раз повторяется) if (preg_match("!<title>(.*?)</title>!si",$string,$ok)) echo "Тег найден, текст: $ok[1]"; else echo "Тег не найден"; Найти текст, заключенный в какой-то тег и заменить его на другой тег, например: <TITLE> ... </TITLE> заменить аналогично на <МОЙ_ТЕГ> ... </МОЙ_ТЕГ> в HTML-файле: PHP: preg_replace("!<title>(.*?)</title>!si","<МОЙ_ТЕГ>\\1</МОЙ_ТЕГ>",$string);
Даж не знаю... помоему для азов - статья слишком простая. Имхо, лучше было бы написать статью про крутые регулярки, а не про элементарные. Что-то из серии ББ кодов с хорошими фильтрами, чтоб народ учился их сам писать. Ну или там с модификатором /e. Еще не заметл жирную надпись в самом начале "для простого поиска/замены" используется strpos и str_replace а не регулярки!!!".=)) Многие, познав такую вещь как regexp начинают ей злоупотреблять почем зря =\ UPD только сейчас заметил: "можт все же перевести на ВВ-теги форума?" - думаю надо. Большинство людей для других целей их и не использует. А безопасность BBкодов + там фильтрация на вложенные 2ые, и 3ые тэги - вообще сама по себе интересная тема, если осилишь
ок, щас распознавалку бб кодов распишу подробно (самописка) ---добавлено--- Почемуто многие самописные сайты разрешают штмл в своей админке, уж не из-за того ли, что создателям "влом" писать распознавалку бб тегов? вот простейший пример: PHP: <? // исходное сообщение: // ------------------------------------------------------ $str=' Памагите, ничаво не работает! Вот пример: [ph p ] // comment # comment phpinfo(); [/ph p] содран с: [url]http://yandex.ru/[/url] ляляля ляляля [b]ПОМОГИТЕ!!![/b] [ph p] for ($i=0; $i<100; $i++) { ping("-f","www.ru"); } [/ph p] [HIDE]тут хайд))) токо что в нем написать?[/HIDE] <? echo "<a href=http://php.spb.ru/chat/>click here!</a>"; phpinfo(); ?> '; // ------------------------------------------------------ // подавить предупреждения (в highlight_string есть глюки) error_reporting(0); // функция подсвечивания одного куска текста function _my_($s,$a1,$a2) { if ($a1!="<?") { $a1="<?"; $a2="?>"; } $s=str_replace("\\\"","\"",$s); ob_start(); highlight_string($a1.$s.$a2); $s=ob_get_contents(); ob_end_clean(); return $s; } // ищем в тексте все куски между <?... или [php]... $str=preg_replace("!(\[php\]|<\?)(.*?)(\[/php\]|\?>)!ise","_my_('\\2','\\1','\\3')",$str); $order = array('[center]','[/center]','[left]','[/left]','[right]','[/right]','[b]','[/b]'); $replace = array('<div align="center">','</div>','<div align="left">','</div>','<div align="right">','</div>','<B>','</B>'); $str = str_replace($order, $replace, $str); // хайд ) if($_GET['member']==='1') { $str = ereg_replace("\[HIDE\](.*)\[\/HIDE\]","<HR>\\1<HR>", $str); $str = ereg_replace("\[URL\]([[:alpha:]]+://[^<>[:space:]]+[[:alnum:]/])\[\/URL\]","<a href=\"\\1\" target=\"blank\">\\1</a>", $str); }else { $str = ereg_replace("\[HIDE\](.*)\[\/HIDE\]","<HR><b>Стань мембром! или не видать тебе хайдов и линков!!!</b><HR>", $str); $str = ereg_replace("\[URL\]([[:alpha:]]+://[^<>[:space:]]+[[:alnum:]/])\[\/URL\]","<b>Стань мембром! или не видать тебе хайдов и линков!!!</b>", $str); } echo $str; ?> тут мы использовали несколько красивых регулярок для наших бб тегов: PHP: $str = ereg_replace("\[HIDE\](.*)\[\/HIDE\]","<HR>\\1<HR>", $str); - заменяет текст, между [HIDE] и [/HIDE] на тот же текст, но в тегах <HR>, чтобы выделить его из общей массы. (конечно, нужно юзать ксс, чтобы было читабельнее)) PHP: $str = ereg_replace("\[URL\]([[:alpha:]]+://[^<>[:space:]]+[[:alnum:]/])\[\/URL\]","<a href=\"\\1\" target=\"blank\">\\1</a>", $str); а эта регулярка обрабатывает урл адрес. ЭТО ТОЛЬКО МОДЕЛЬ! нужно во-первых, текст, отображаемый пользователю разбивать на участки, во избежание XSS атак, да и фильтровать его Заметьте, срабатывают эти регулярки, только если if($_GET['member']==='1') - истинно (так мы упростили систему авторизации), если же это ложно, то вместо хайдов выводится: HTML: <HR><b>Стань мембром! или не видать тебе хайдов и линков!!!</b><HR> и вместо линков то же самое, сделано это чуть измененными регулярками: PHP: $str = ereg_replace("\[HIDE\](.*)\[\/HIDE\]","<HR><b>Стань мембром! или не видать тебе хайдов и линков!!!</b><HR>", $str); $str = ereg_replace("\[URL\]([[:alpha:]]+://[^<>[:space:]]+[[:alnum:]/])\[\/URL\]","<b>Стань мембром! или не видать тебе хайдов и линков!!!</b>", $str); К тому же, мы и заменяем теги , на аналогичные штмл вот таким кодом: PHP: $order = array('[center]','[/center]','[left]','[/left]','[right]','[/right]','[b]','[/b]'); $replace = array('<div align="center">','</div>','<div align="left">','</div>','<div align="right">','</div>','<B>','</B>'); $str = str_replace($order, $replace, $str); теперь о проблемах такой схемы. заметили, что я выложил пшп код не в тегах ? а почему? дело в том, что вобла пользуется аналогичным алгоритмом, который я описал, ей наплевать на правильную "скобочную" последовательность! как например [p hp][p hp][/ph p][/ph p] такой код она сглотит как: [ph p][p hp][/p hp] и отдельно стоящий [/ph p]. плохо, правда? как же этого избежать? можно юзать правильно настроенные регулярки в отношении жадности, а можно пойти совсем другим алгоритмом, его я опишу лиш на словах, т.к. нормальную версию кодю уже недельку) суть, мы разбиваем сообщение на "части" учитывая правильные скобочные последовательности, и работаем с ними функциями, например, в теге пшп запрещены теги и т.д. Но, почему же вбуллетин не использует это? да потому, что тогда полетит к черту вся система плагиноВ, точнее она не полетит, ее можно будет сделать, но уже только с помощью графов (более простого метода мне в голову пока не лезет ). а так каждый модуль, как например тег "оффтом" на аллчитс добавляет еще 1 регулярку. Тема очень обширная, поэтому если есть вопросы, пишите) да и от предложений тоже не откажусь)))) ЗЫ проблему с PHP: решил, просто пробелов понавставлял)))
согласен, также основа - explode(); imdplode(); )вот те статья - продвинутые реги http://www.intuit.ru/department/pl/plphp/class/free/13/5.html(мало, но тонкость, что приятно /сумеешь обмозговать и передать простым языком и со смешанными примерами - цены тебе не будет)) имхо, не вижу смысла описывать реги, и писать целую статью на тему. Материала уйма, и не так сложно найти понятное изложение.. ну да ладно, теперь на вопры по регам буду ссылку давать.. зы: репу зарабатываешь))
в конце статьи я и спросил про целесообразность про репу: есть более простые методы, чем про регулярки рассказывать) если хочешь, покажу )))
Угу, есть. Так что не думаю что автор за ней гоняется, имхо ) Talisman я там один пост выше апдейтил, может ты не заметил. Не рискнешь сделать статью про безопасные ББ коды? Т.е. показать как делать ББкоды максимально устойчивые к КСС (с хорошей фильтрацией вложенных тегов). Это конечно труд непосильный, тут тебе действительно цены не будет. Я бы даже присоединился/присоединюсь к разработке, если в армию не заберут в ближайшие два месяца ))) Сам давно этим вопросом занимаюсь. Конечно всегда есть ризон выдернуть класс для обработки ббкодов из того же vbulletin'a, но все таки желание изобрести велосипед так и прет в этом вопросе =\\ ЗЫ целесообразность в вопросе регулярок есть всегда, главное правильно это дело представить. Эта статья (фактически ликбез) все таки немного не то. Как сделать "то", не спрашивай ))