Несколько примеров на регулярные выражения
Автор: Дмитрий Бородин
Полезные ссылки:
Элементарные действия
Является ли строка числом, длиной до 77 цифр:
if (ereg("^[0-9]{1,77}$",$string)) echo "yes"; else echo "no";
|
Состоит ли строка только из букв, цифр и "_", длиной от 5 до 20 символов:
if (ereg("^[a-zа-я0-9_]{5,20}$",$string)) echo "yes"; else echo "no";
|
Есть ли в строке любые символы, кроме допустимых. Допустимыми считаются
буквы, цифры и "_". Длину тут проверять нельзя,
разве что просто дополнительным условием strlen($string). Не путайте с предыдущим
примером - хоть результат и одинаковый, но метод другой, "от противного" :)
if ( ! ereg("[^a-zа-я0-9_]",$string))
echo "нет посторонних букв (OK)";
else
echo "есть посторонние буквы (FALSE)";
|
Для регистро независимого сравнения используйте eregi().
Есть ли в строке идущие подряд символы, не менее 3-х символов
подряд (типа "абвгДДДеё", но не "ааббаабб"):
if (preg_match("/(.)\\1\\1/",$string)) echo "yes"; else echo "no";
|
Заменить везде в тексте СТРОКУ1 на СТРОКУ2 (задача решается без регегулярных
выражений):
$string=str_replace("СТРОКА1","СТРОКА2",$string);
|
Заменить кривые коды перехода строки на нормальные: для
этого нужно только удалить "\r". Переходы бывают нормальными (но разными!):
"\n" или "\r\n". Еще бывают глюки, типа "\r\r\n".
$string=str_replace("\r","",$string);
|
Заменить все повторяющиеся пробелы на один.
Не пытайтесь здесь применить str_replace, это хорошая функция, но не
для данного примера.
$string=preg_replace("/ХХ+/","Х",$string); // вместо Х поставьте пробел
|
В тексте есть некоторые слова, допустим "СЛОВО" и "ЛЯЛЯЛЯ" (и т.д.),
которые нужно одинаковым образом заменить на тоже самое, но
с добавками. Возможно, слова отсутствуют или встречаются много раз
в любом регистре.
Т.е. если было "слово" или "СлОвО" (или еще как),
нужно заменить это на "<b>слово</b>" или "<b>СлОвО</b>" (смотря, как было).
Другими словами нужно найти перечень слов в любом регистре и вставить
по краям найленных слов фиксированные строки (на "<b>" и "</b>").
$string=preg_replace("/(слово1|слово2|ляляля|слово99)/si","<b>\\1</b>",$string);
|
Найти текст, заключенный в какой-то тег, например <TITLE> ... </TITLE> из HTML-файла ($string -
исходный текст).
if (preg_match("!<title>(.*?)</title>!si",$string,$ok))
echo "Тег найден, текст: $ok[1]";
else
echo "Тег не найден";
|
Найти текст, заключенный в какой-то тег и заменить его на
другой тег, например: <TITLE> ... </TITLE> заменить аналогично на <МОЙ_ТЕГ> ... </МОЙ_ТЕГ> в HTML-файле:
preg_replace("!<title>(.*?)</title>!si","<МОЙ_ТЕГ>\\1</МОЙ_ТЕГ>",$string);
|
Подсветка PHP-кода в сообщениях
К примеру, у вас есть форум типа vBulletin, где можно подсвечивать код,
если его выделить специально: [PHP] любой код [/PHP].
В итоге, после этого (при просмотре сообщения), получается
красивый и цветной php-код.
И так, если вы хотите, чтобы все куски между [PHP]..[/PHP] и <?..?> воспринимались как код и раскрашивались, то это можно сделать
довольно легко.
Текст программы.
<?
// исходное сообщение:
// ------------------------------------------------------
$str='
Памагите, ничаво не работает! Вот пример:
[php]
// comment
# comment
phpinfo();
[/php]
ляляля ляляля
[php]
for ($i=0; $i<100; $i++) {
ping("-f","www.ru");
}
[/php]
<?
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);
echo $str;
?>
|
После такой программы на экране получается:
Памагите, ничаво не работает! Вот пример: <?
// comment
# comment
phpinfo();
?> ляляля ляляля <?
for ($i=0; $i<100; $i++) {
ping("-f","www.ru");
}
?> <?
echo "<a href=http://php.spb.ru/chat/>click here!</a>";
phpinfo();
?> |
Как видно, все, что было между спец.строками подсветилось,
а посторонний текст никак не изменился. Если вы собираетесь применять для
форума, то подумайте и о переходах на новые строчки.
Если у вас все сообщение - это сплошной код, то используйте highlight_string
напрямую, без поиска <?..?> в коде...
Проверка URL на корректность
Это функция взята из исходников чата.
Поддерживает все, что только может быть в УРЛ...
Помните о том, что вы должны не только проверять, но и принимать новое значение
от функции, т.к. та дописывает "http://" в случае его отсутствия.
// доп. функция для удаления опасных сиволов
function pregtrim($str) {
return preg_replace("/[^\x20-\xFF]/","",@strval($str));
}
//
// проверяет URL и возвращает:
// * +1, если URL пуст
// if (checkurl($url)==1) echo "пусто"
// * -1, если URL не пуст, но с ошибками
// if (checkurl($url)==-1) echo "ошибка"
// * строку (новый URL), если URL найден и отпарсен
// if (checkurl($url)==0) echo "все ок"
// либо if (strlen(checkurl($url))>1) echo "все ок"
//
// Если протокола не было в URL, он будет добавлен ("http://")
//
function checkurl($url) {
// режем левые символы и крайние пробелы
$url=trim(pregtrim($url));
// если пусто - выход
if (strlen($url)==0) return 1;
//проверяем УРЛ на правильность
if (!preg_match("~^(?:(?:https?|ftp|telnet)://(?:[a-z0-9_-]{1,32}".
"(?::[a-z0-9_-]{1,32})?@)?)?(?:(?:[a-z0-9-]{1,128}\.)+(?:com|net|".
"org|mil|edu|arpa|gov|biz|info|aero|inc|name|[a-z]{2})|(?!0)(?:(?".
"!0[^.]|255)[0-9]{1,3}\.){3}(?!0|255)[0-9]{1,3})(?:/[a-z0-9.,_@%&".
"?+=\~/-]*)?(?:#[^ '\"&<>]*)?$~i",$url,$ok))
return -1; // если не правильно - выход
// если нет протокала - добавить
if (!strstr($url,"://")) $url="http://".$url;
// заменить протокол на нижний регистр: hTtP -> http
$url=preg_replace("~^[a-z]+~ie","strtolower('\\0')",$url);
return $url;
}
|
Таким образом для проверки нужно использовать нечто такое:
$url=checkurl($url); // перезаписали УРЛ в самого себя
if ($url) exit("Ошибочный URL");
|
Проверка правильности E-mail
//
// проверяет мыло и возвращает
// * +1, если мыло пустое
// * -1, если не пустое, но с ошибкой
// * строку, если мыло верное
//
function checkmail($mail) {
// режем левые символы и крайние пробелы
$mail=trim(pregtrim($mail)); // функцию pregtrim() возьмите выше в примере
// если пусто - выход
if (strlen($mail)==0) return 1;
if (!preg_match("/^[a-z0-9_-]{1,20}@(([a-z0-9-]+\.)+(com|net|org|mil|".
"edu|gov|arpa|info|biz|inc|name|[a-z]{2})|[0-9]{1,3}\.[0-9]{1,3}\.[0-".
"9]{1,3}\.[0-9]{1,3})$/is",$mail))
return -1;
return $mail;
}
|
Проверять аналогично предыдущему примеру.
Если кажется, что слишком сложный рег для проверки мыла, то вот тут
лежит настоящее регулярное выражение, соответствующее спецификации для
проверки email: mail.txt.
Вырезание URL из текста и кривых HTML-файлов
Иногда нужно вырезать из HTML-текст ссылки на URL или Email.
Если у вас в HTML нет заведомо кривого кода, то это очень простая
задача на регулярное выражение типа:
<a[^>]+href=([^ >]+)[^>]*>(.*?)</a>
|
Но ссылки бывают разные... Как делать вашу программу, решать вам.
Можно брать только 100% верные ссылки, но тогда некоторые кривые
сслыки не попадут (хотя они тоже верные). Можно брать все подряд,
но тогда кое-какие ссылки будут не совсем корректно вырезаться.
Текст программы:
<?
$str="
<a href=url1>name1</a>
<a href=url2>name2</a>
<a href='url3'>name3</a>
<a href=url4>< скобки ></a>
<a href=\"url5\"><b>жирно</b></a>
<a href=url6>\"кавычки\"</a>
<a target=\"<попытка обхитрить программу> хахаха\" href=url7>77777</a>
<a href=url8 target=\"<попытка обхитрить программу> хахаха\" >88888</a>";
echo "<pre>Исходный код:".htmlspecialchars($str)."</pre>";
echo "---------------Вариант 1---------------";
preg_match_all("!<a.*?href=\"?'?([^ \"'>]+)\"?'?.*?>(.*?)</a>!is",$str,$ok);
for ($i=0; $i<count($ok[1]); $i++) {
echo "<li>".$ok[1][$i]." - ".$ok[2][$i];
}
echo "<br>---------------Вариант 2---------------";
preg_match_all("!<a[^>]+href=\"?'?([^ \"'>]+)\"?'?[^>]*>(.*?)</a>!is",$str,$ok);
for ($i=0; $i<count($ok[1]); $i++) {
echo "<li>".$ok[1][$i]." - ".$ok[2][$i];
}
echo "<br>---------------Вариант 3---------------";
preg_match_all("!<a[^>]+href=\"?'?([^ \"'>]+)\"?'?[^>]*>([^<>]*?)</a>!is",$str,$ok);
for ($i=0; $i<count($ok[1]); $i++) {
echo "<li>".$ok[1][$i]." - ".$ok[2][$i];
}
?>
|
Результат исполнения примера:
Исходный код:
<a href=url1>name1</a>
<a href=url2>name2</a>
<a href='url3'>name3</a>
<a href=url4>< скобки ></a>
<a href="url5"><b>жирно</b></a>
<a href=url6>"кавычки"</a>
<a target="<попытка обхитрить программу> хахаха" href=url7>77777</a>
<a href=url8 target="<попытка обхитрить программу> хахаха" >88888</a>
---------------Вариант 1---------------
url1 - name1
url2 - name2
url3 - name3
url4 - < скобки >
url5 - жирно
url6 - "кавычки"
url7 - 77777
url8 - хахаха" >88888
---------------Вариант 2---------------
url1 - name1
url2 - name2
url3 - name3
url4 - < скобки >
url5 - жирно
url6 - "кавычки"
url8 - хахаха" >88888
---------------Вариант 3---------------
url1 - name1
url2 - name2
url3 - name3
url6 - "кавычки" |