Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей.
Здесь обсуждаются безопасность, программирование, технологии и многое другое.
Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
 |
Регулярные выражения [Beta-version] |

20.03.2007, 11:26
|
|
Постоянный
Регистрация: 22.04.2006
Сообщений: 566
Провел на форуме: 1325772
Репутация:
517
|
|
Регулярные выражения [Beta-version]
Привет, все же эта статья не о моих мыслях, а о созданном до меня творении - регулярных выраженийх, то не буду копипастить "заводские" мануалы, а сразу перейду к делу.
Регулярные выраженияКак всегда, материал для затравки:
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/functio...-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...-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
жду камментов)
|
|
|

20.03.2007, 11:30
|
|
Флудер
Регистрация: 20.11.2006
Сообщений: 3,316
Провел на форуме: 16641028
Репутация:
2371
|
|
|
|
|

20.03.2007, 11:52
|
|
Постоянный
Регистрация: 22.04.2006
Сообщений: 566
Провел на форуме: 1325772
Репутация:
517
|
|
Элементарные действия
Является ли строка числом, длиной до 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);
|
|
|

20.03.2007, 12:06
|
|
Постоянный
Регистрация: 17.09.2005
Сообщений: 375
Провел на форуме: 993362
Репутация:
175
|
|
Даж не знаю... помоему для азов - статья слишком простая. Имхо, лучше было бы написать статью про крутые регулярки, а не про элементарные. Что-то из серии ББ кодов с хорошими фильтрами, чтоб народ учился их сам писать. Ну или там с модификатором /e.
Еще не заметл жирную надпись в самом начале "для простого поиска/замены" используется strpos и str_replace а не регулярки!!!".=)) Многие, познав такую вещь как regexp начинают ей злоупотреблять почем зря =\
UPD только сейчас заметил: "можт все же перевести на ВВ-теги форума?" - думаю надо. Большинство людей для других целей их и не использует. А безопасность BBкодов + там фильтрация на вложенные 2ые, и 3ые тэги - вообще сама по себе интересная тема, если осилишь 
Последний раз редактировалось Abra; 20.03.2007 в 12:08..
|
|
|

20.03.2007, 12:08
|
|
Постоянный
Регистрация: 22.04.2006
Сообщений: 566
Провел на форуме: 1325772
Репутация:
517
|
|
ок, щас распознавалку бб кодов распишу подробно (самописка)
---добавлено---
Почемуто многие самописные сайты разрешают штмл в своей админке, уж не из-за того ли, что создателям "влом" писать распознавалку бб тегов?
вот простейший пример:
[php]<?
// исходное сообщение:
// ------------------------------------------------------
$str='
Памагите, ничаво не работает! Вот пример:
[ph p ]
// comment
# comment
phpinfo();
[/ph p]
содран с: http://yandex.ru/
ляляля ляляля
ПОМОГИТЕ!!!
[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);
К тому же, мы и заменяем теги [center], [b] на аналогичные штмл вот таким кодом:
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]. плохо, правда? как же этого избежать? можно юзать правильно настроенные регулярки в отношении жадности, а можно пойти совсем другим алгоритмом, его я опишу лиш на словах, т.к. нормальную версию кодю уже недельку)
суть, мы разбиваем сообщение на "части" учитывая правильные скобочные последовательности, и работаем с ними функциями, например, в теге пшп запрещены теги [b] и т.д.
Но, почему же вбуллетин не использует это? да потому, что тогда полетит к черту вся система плагиноВ, точнее она не полетит, ее можно будет сделать, но уже только с помощью графов (более простого метода мне в голову пока не лезет  ). а так каждый модуль, как например тег "оффтом" на аллчитс добавляет еще 1 регулярку.
Тема очень обширная, поэтому если есть вопросы, пишите)
да и от предложений тоже не откажусь))))
ЗЫ проблему с [php] решил, просто пробелов понавставлял)))
Последний раз редактировалось Talisman; 20.03.2007 в 13:03..
|
|
|

20.03.2007, 15:21
|
|
Участник форума
Регистрация: 12.12.2006
Сообщений: 158
Провел на форуме: 1364740
Репутация:
114
|
|
Сообщение от Abra
Даж не знаю... помоему для азов - статья слишком простая. Имхо, лучше было бы написать статью про крутые регулярки, а не про элементарные. Что-то из серии ББ кодов с хорошими фильтрами, чтоб народ учился их сам писать. Ну или там с модификатором /e.
Еще не заметл жирную надпись в самом начале "для простого поиска/замены" используется strpos и str_replace а не регулярки!!!".=)) Многие, познав такую вещь как regexp начинают ей злоупотреблять почем зря =\
согласен, также основа - explode(); imdplode();
)вот те статья - продвинутые реги http://www.intuit.ru/department/pl/plphp/class/free/13/5.html(мало, но тонкость, что приятно /сумеешь обмозговать и передать простым языком и со смешанными примерами - цены тебе не будет))
имхо, не вижу смысла описывать реги, и писать целую статью на тему. Материала уйма, и не так сложно найти понятное изложение.. ну да ладно, теперь на вопры по регам буду ссылку давать..
зы: репу зарабатываешь))
Последний раз редактировалось mR_LiNK[deface_0nl; 20.03.2007 в 15:40..
|
|
|

20.03.2007, 15:23
|
|
Постоянный
Регистрация: 22.04.2006
Сообщений: 566
Провел на форуме: 1325772
Репутация:
517
|
|
Сообщение от mR_LiNK[deface_0nl
согласен, также основа - explode(); imdplode();
)вот те статья - продвинутые реги http://www.intuit.ru/department/pl/plphp/class/free/13/5.html
имхо, не вижу смысла описывать реги, и писать целую статью на тему. Материала уйма, и не так сложно найти понятное изложение.. ну да ладно теперь на вопры по регам буду ссылку давать..
зы: репу зарабатываешь))
в конце статьи я и спросил про целесообразность
про репу: есть более простые методы, чем про регулярки рассказывать) если хочешь, покажу )))
|
|
|

20.03.2007, 15:24
|
|
Постоянный
Регистрация: 22.04.2006
Сообщений: 566
Провел на форуме: 1325772
Репутация:
517
|
|
да, забыл, спасибо за линк)
тогда уж получится хорошая подборка линков на мануалы)
|
|
|

20.03.2007, 16:32
|
|
Постоянный
Регистрация: 17.09.2005
Сообщений: 375
Провел на форуме: 993362
Репутация:
175
|
|
про репу: есть более простые методы, чем про регулярки рассказывать) если хочешь, покажу )))
Угу, есть. Так что не думаю что автор за ней гоняется, имхо )
Talisman я там один пост выше апдейтил, может ты не заметил. Не рискнешь сделать статью про безопасные ББ коды? Т.е. показать как делать ББкоды максимально устойчивые к КСС (с хорошей фильтрацией вложенных тегов). Это конечно труд непосильный, тут тебе действительно цены не будет. Я бы даже присоединился/присоединюсь к разработке, если в армию не заберут в ближайшие два месяца ))) Сам давно этим вопросом занимаюсь. Конечно всегда есть ризон выдернуть класс для обработки ббкодов из того же vbulletin'a, но все таки желание изобрести велосипед так и прет в этом вопросе =\\
ЗЫ целесообразность в вопросе регулярок есть всегда, главное правильно это дело представить. Эта статья (фактически ликбез) все таки немного не то. Как сделать "то", не спрашивай ))
|
|
|
|
 |
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|