
<h1 class=p1>Perl-совместимые регулярные выражения</h1>
<br>
<br>

<p class=text>PHP поддерживает ряд функций для работы с Perl-совместимыми регулярными выражениями (PCRE - Perl Compatible Regular Expression). Такие выражения заключаются в ограничители, в качестве которых, как правило, используется прямой слеш:</p>
<blockquote><pre>
/mail/
</pre></blockquote>
<p class=text>Это выражение соответствует строке, содержащей слово "mail".</p>
<p class=text>За ограничителями могут следовать <b>модификаторы</b>, уточняющие регулярное выражение. Наиболее часто используют следующие модификаторы:</p>
<ul>
  <li><b>i</b> (Игнорировать регистр при поиске соответствия. Т. е. выражение "/mail/i" будет соответствовать как строке "MAIL", так и строке "mail".);</li>
  <li><b>x</b> (Игнорировать пробельные символы).</li>
</ul>
<p class=text>Для PCRE-выражений характерно применение <b>общих типов символов</b>, которые аналогичны классам символов для регулярных выражений в стиле POSIX. Наиболее часто встречающиеся общие типы символов приведены ниже.</p>
<ul>
  <li><b>\d</b> - соответствие десятичной цифре</li>
  <li><b>\D</b> - соответствие любому символу, за исключением десятичных цифр</li>
  <li><b>\s</b> - соответствие пробельным символам</li>
  <li><b>\S</b> - соответствие любым символам, кроме пробельных</li>
  <li><b>\h</b> - наличие границы слова</li>
  <li><b>\B</b> - отсутствие границы слова</li>
  <li><b>\Z</b> - конец строки или символ перевода конца строки</li>
  <li><b>\A</b> - начало строки</li>
</ul>
<p class=text>Теперь рассмотрим основные функции, которые есть в PHP для работы с PCRE-выражениями.</p>
<h3 class=p1>preg_match()</h3>
<blockquote><pre>
  <em class=gr>int</em> <b>preg_match</b><em class=gr> (string</em><b> pattern</b>,<em class=gr> string</em><b> subject</b> [,<em class=gr> array</em><b> matches</b>]<em class=gr>)</em>
</pre></blockquote>
<p class=text>Эта функция ищет в строке <b>subject</b> соответствие регулярному выражению <b>pattern</b>. Если задан необязательный параметр <b>matches</b>, то результаты поиска помещаются в массив.</p>
<p class=text>Приведем несколько примеров.</p>
<blockquote><pre>
<em class=red>&lt;?</em>
  <b>$str</b><em class=gr> = </em>"PHP один из лучших языков программирования для Web"<em class=gr>;</em>
  <b>if</b><em class=gr> (</em><b>preg_match</b><em class=gr> (</em>"/php/i", <b>$str</b><em class=gr>)) 
  {
    echo(</em>"Соответствие найдено"<em class=gr>);
  }</em>
  <b>else</b><em class=gr>
  {
    echo(</em>"Соответствие не найдено"<em class=gr>);
  }</em>
<em class=red>?&gt;</em>
</pre></blockquote>
<p class=text>Результат:</p>
<blockquote><pre>
Соответствие найдено
</pre></blockquote>
<blockquote><pre>
<em class=red>&lt;?</em>
  <b>$str</b><em class=gr> = </em>"PHP один из лучших языков программирования для Web"<em class=gr>;</em>
  <b>if</b><em class=gr> (</em><b>preg_match</b><em class=gr> (</em>"/\bweb\b/i", <b>$str</b><em class=gr>)) 
  {
    echo(</em>"Соответствие найдено"<em class=gr>);
  }</em>
  <b>else</b><em class=gr>
  {
    echo(</em>"Соответствие не найдено"<em class=gr>);
  }</em>
<em class=red>?&gt;</em>
</pre></blockquote>
<p class=text>Результат:</p>
<blockquote><pre>
Соответствие найдено
</pre></blockquote>
<blockquote><pre>
<em class=red>&lt;?</em>
  //<em class=comnt> получаем www-адрес (имя хоста) из url</em>
  <b>$url</b><em class=gr> = </em>"http://www.php.net/download.html"<em class=gr>;</em>
  <b>preg_match</b><em class=gr>(</em>"/^(http:\/\/)?([^\/]+)/i", <b>$url</b>, <b>$matches</b><em class=gr>);</em>
  <b>$host</b><em class=gr> = </em><b>$matches[2]</b><em class=gr>;
  echo(</em>"www-адрес: <b>$host</b>"<em class=gr>);
  echo(</em>"&lt;br&gt;"<em class=gr>);</em>
  //<em class=comnt> получаем последние два сегмента имени хоста (доменное имя)</em>
  <b>preg_match</b><em class=gr>(</em>"/[^\.\/]+\.[^\.\/]+$/", <b>$host</b>, <b>$matches</b><em class=gr>);
  echo</em> "доменное имя: {<b>$matches[0]</b>}\n"<em class=gr>;</em>
<em class=red>?&gt;</em>
</pre></blockquote>
<p class=text>Результат:</p>
<blockquote><pre>
www-адрес: www.php.net
доменное имя: php.net
</pre></blockquote>
<h3 class=p1>preg_replace()</h3>
<blockquote><pre>
<em class=gr>mixed</em><b> preg_replace</b><em class=gr> (mixed </em><b>pattern</b>, <em class=gr>mixed</em><b> replacement</b>, <em class=gr>mixed </em><b>subject</b>
                            [,<em class=gr>int</em><b> limit</b>]<em class=gr>)</em>
</pre></blockquote>
<p class=text>Эта функция ищет в строке <b>subject</b> соответствия регулярному выражению <b>pattern</b>, и заменяет их на <b>replacement</b>. Необязательного параметр <b>limit</b> задает число соответствий, которые надо заменить. Если этот параметр не указан, или равен -1, то заменяются все найденные соответствия.</p>
<blockquote><pre>
<em class=red>&lt;?</em>
  <b>$str</b><em class=gr> = </em>"May 15, 2003"<em class=gr>;</em>
  <b>$pattern</b><em class=gr> = </em>"/(\w+) (\d+), (\d+)/i"<em class=gr>;</em>
  <b>$replacement</b><em class=gr> = </em>"1 \${1} \$3"<em class=gr>;
  print</em><b> preg_replace</b><em class=gr>(</em><b>$pattern</b>, <b>$replacement</b>, <b>$str</b><em class=gr>);</em>
<em class=red>?&gt;</em>
</pre></blockquote>
<p class=text>Результат:</p>
<blockquote><pre>
1 May 2003
</pre></blockquote>
<p class=text>А вот как можно написать функцию, которая будет практически полным аналогом функции <b>htmlspecialchars</b>.</p>
<blockquote><pre>
<em class=red>&lt;?</em>
  <b>function my_htmlspecialchats</b><em class=gr>(</em><b>$document</b><em class=gr>)
  {</em>
    <b>$search</b><em class=gr> = array (</em>"'<script[^>]*?>.*?</script>'si",  
                     "'<[\/\!]*?[^<>]*?>'si",           
                     "'([\r\n])[\s]+'",                 
                     "'&(quot|#34);'i",                 
                     "'&(amp|#38);'i",
                     "'&(lt|#60);'i",
                     "'&(gt|#62);'i",
                     "'&(nbsp|#160);'i",
                     "'&(iexcl|#161);'i",
                     "'&(cent|#162);'i",
                     "'&(pound|#163);'i",
                     "'&(copy|#169);'i",
                     "'&#(\d+);'e"<em class=gr>);</em>
    <b>$replace</b><em class=gr> = array (</em>"",
                      "",
                      "\\1",
                      "\"",
                      "&",
                      "<",
                      ">",
                      " ",
                      chr(161),
                      chr(162),
                      chr(163),
                      chr(169),
                      "chr(\\1)"<em class=gr>);</em>
    <b>$text</b><em class=gr> = </em><b>preg_replace</b><em class=gr> (</em><b>$search</b>, <b>$replace</b>, <b>$document</b><em class=gr>);</em>
    <b>return $text</b><em class=gr>;
  }</em>
  <b>$doc</b><em class=gr> = </em>"<javascript>alert;</script>"; //<em class=comnt> напишем java-скрипт</em>
  <b>my_htmlspecialchats</b><em class=gr>(</em><b>$doc</b><em class=gr>);</em>  //<em class=comnt> выводит "alert;"</em>
  <em class=gr>echo(</em><b>$doc</b><em class=gr>);</em>
<em class=red>?&gt;</em>
</pre></blockquote>
