создать свой сайт на PHP, HTML, CSS
28.01.2012

Мы рекомендуем


RSS

rss новости   rss статьи

Несколько примеров на регулярные выражения


Элементарные действия

Является ли строка числом, длиной до 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" или "rn". Еще бывают глюки, типа "rrn".

$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] и <?..?> воспринимались как код и раскрашивались, то это можно сделать довольно легко.

Текст программы.

   // подавить предупреждения (в 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;

?>

Как видно, все, что было между спец.строками подсветилось, а посторонний текст никак не изменился. Если вы собираетесь применять для форума, то подумайте и о переходах на новые строчки. Если у вас все сообщение - это сплошной код, то используйте 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;
}

Проверять аналогично предыдущему примеру.

Вырезание 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",$s
tr,$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 - "кавычки"