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

Автор: content Понедельник, Апрель 9th, 2012 Нет комментариев

Рубрика: Язык PHP

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

Является ли строка числом, длиной до 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('\')",$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 — «кавычки»

Автор: Дмитрий Бородин

Источник: http://www.php.su/articles/?cat=regexp&page=004

Оставить комментарий

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты