Регулярные выражения

Основы регулярных выражений

http://old.code.mu/tasks/php/regular/rab...

$p = strrpos($inFile, '.'); 
 if ($p) $outFile = substr($inFile, 0, $p);
else $outFile = $inFile;
$outFile .= ".out";

Давайте смотреть, функия strpos возращает порядковый номер позиции элемента в строке. Если, например, строка "abc", то strpos (abc,a) возвратит цифру ноль если, например символ не присутсвует в строке то функция вернет false. Так как строка это массив символов. А подсчет в массиве начинается с нуля. Пример c cайта:

<?php
$mystring = 'abc';
$findme   = 'c';
$pos = strpos($mystring, $findme);
if ($pos === false) {
    echo "Строка '$findme' не найдена в строке '$mystring";
} else {
    echo "Строка '$findme' найдена в строке '$mystring'";
    echo " в позиции $pos";
}
//  Зачем где и когда используется знак тройного равенства
$pos = strpos($newstring, 'a', 1); // здесь мы подбираем символ 'a' с 1 позиции, включая 1 позицией
?>
// И вторая функция substr
$rest = substr("abcdef", 0, 4); // возвращает "abcd"
<?php
$fullPath="D:\N";
$slash1 = strrpos($fullPath, '/');
$slash2 = strrpos($fullPath, '\\');
$slash = max($slash1, $slash2);
$dirName = substr($fullPath, 0, $slash);
echo "Directory: ".$dirName."<BR>"; // Выведет "Directory: D"
$filename = substr($fullPath, $slash + 1, 10000); // "Выведет N"
echo   $filename;
?>
<?php ## Модель скрипта, принимающего текст от пользователя
if (@$_REQUEST['text'])
echo htmlspecialchars($_REQUEST['text'])."<hr />";
?>
<form action="<?=$_SERVER['SCRIPT_NAME']?>" method="POST">
<textarea name="text" cols="60" rows="10">
<?=@htmlspecialchars($_REQUEST['text'])?>
</textarea><br />
<input type="submit">
</form>

Работа с регулярными выражениями на PHP:
Глава 1

<?php
            // str_replace(что меняем, на что меняем, где меняем)
	 // preg_replace(что меняем, на что меняем, где меняем)

	echo str_replace('a', '!', 'aabbaa')."\n"; //выведет '!!bb!!'
	echo preg_replace('#a#', '!', 'aabbaa'); //выведет '!!bb!!'
?>

Глава 2
Глава 3
Глава 4

<?php


/*
// проверить что в строке есть число (одна цифра или больше)
preg_match('/(\d+)/s',"article_123.html", $matches);
// совпадение (подвыражение в скобках) окажется в $matches[1];
echo $matches[1]; // выводит 123
*/
preg_match('/(\S+)@([a-z0-9.]+)/is',"article_123.html","Привет от somebody@mail.ru!",$m);
// Совпадение (подвыражение в скобках) окажется в $matches[1]
echo "В тексте найдено: ящик -$m[1], хост - $m[2]";
?>
preg_match('/(\S+)@([a-z0-9.]+)/is', "Привет от somebody@mail.ru!", $m);
// Совпадение (подвыражение в скобках) окажется в $matches[1]
echo "В тексте найдено: ящик -$m[1], хост - $m[2]";

Будет выведено:

В тексте найдено: ящик -somebody, хост - mail.ru

ЧИТАТЬ! https://habr.com/ru/company/otus/blog/48...

Использование регулярных выражений в PHP

Сопоставление с заменой

<?php
  $text = "Привет от somebody@mail.ru, а также от other@mail.ru!";   
  $html = preg_replace(
  '/(\S+)@([a-z0-9.]+)/is',// найти все E-mail     
  '<a href="mailto:$0">$0</a>', // заменить их по шаблону    
   $text   // искать в $text   
);   
   echo $html;
?>

Язык PCRE

Ограничители

/ /i - не учитывать регистр символов

if (preg_match('/path\\/to\\/file/i', "path/to/file"))   echo "совпадение!"; 

Альтернативные ограничители

<?php
echo preg_replace('[(/file)[0-9]+]i', '$1', "/file123.txt"); 
?>

Отмена действия спецсимволов

$re = '/\\\\filename/';
$re = '/\\S+\\\\\\S+/';

Простые символы (литералы)

echo preg_replace('/at/', 'AT', "What is the Perl Compatible Regex?"); 

Классы символов
(.) — обозначает один любой символ
Например, выражение /a.b/s имеет совпадение для строк azb или aqb, но не "срабатывает", скажем, для aqwb или ab. Позже мы рассмотрим, как можно заставить точку обозначать ровно два (или, к примеру, ровно пять) любых символов.
Существует несколько спецсимволов, обозначающих сразу класс букв. Эта возможность — один из краеугольных камней, основ регулярных выражений. Самый важный из таких знаков — точка (.) — обозначает один любой символ. Например, выражение /a.b/s имеет совпадение для строк azb или aqb, но не "срабатывает", скажем, для aqwb или ab. Позже мы рассмотрим, как можно заставить точку обозначать ровно два (или, к примеру, ровно пять) любых символов. В PCRE (в отличие от POSIX) существует еще несколько классов:
\s — соответствует "пробельному" символу: пробелу (" "), знаку табуляции (\t), переносу строки (\n) или возврату каретки (\r);
\S — любой символ, кроме пробельного;
\w — любая буква или цифра;
\W — не буква и не цифра;
\d — цифра от 0 до 9;
\D — все, что угодно, но только не цифра.

Альтернативы
К примеру, выражение /a[xXyY]c/ соответствует строкам, в которых есть подстроки из трех символов, начинающиеся с а, затем одна из букв x, X, y, Y и, наконец, буква c. Если нужно вставить внутрь квадратных скобок символ [ или ], то следует просто поставить перед ним обратный слеш (напоминаем, в строках PHP — два слеша), чтобы отменить его специальное действие.

'/abc[[:alnum:]]+/' # abc, затем одна или более буква или цифра
'/abc[[:alpha:][:punct:]0]/' # abc, далее буква, знак пунктуации или 0

'/abc[\w.]/' Оно ищет подстроку "abc", после которой идет любая буква, цифра или точка.

Отрицательные классы
/]+>/ "срабатывает" на все HTML-теги в строке, поэтому простейший способ удаления тегов выглядит так:
echo preg_replace('/]+>/', '', $text);

Квантификаторы повторений
Выражение /a-*-/ соответствует строке, в которой есть буква a, затем — ноль или более минусов и, наконец, завершающий минус.
Вот пример выражения, которое определяет, есть ли в строке английское слово, написанное через дефис: /[a-zA-Z]+-[a-zA-Z]+/
Например, выражение /[a-zA_Z]+\r?\n/ определяет строки, в которых последнее слово прижато к правому краю строки
Мнимые символы
^ — соответствует началу строки (заметьте: не первому символу строки, а в точ- ности началу строки, позиции перед первым символом);

Мнимые символы
Мнимые символы — это просто участок строки между соседними символами (да, именно так, как это ни абсурдно), удовлетворяющий некоторым свойствам. Фактически мнимый символ — это некая позиция в строке. Например:
^ — соответствует началу строки (заметьте: не первому символу строки, а в точ- ности началу строки, позиции перед первым символом);
ВНИМАНИЕ!
Мы уже раньше встречали этот символ внутри скобок []. Заметьте, что там он обозначал совершенно другое действие: отрицание класса.
$ — соответствует концу строки (опять же, позиции за концом строки);
\b — соответствует началу или концу слова. Фактически любая позиция между \w\W или \W\w заставляет \b "сработать";
\B — любая позиция, кроме начала или конца слова. Чтобы закрепить материал, давайте рассмотрим несколько выражений:
'/^\w:/' — соответствует любой строке, начинающейся с буквы, завершенной двоеточием; абсолютный путь в Windows выглядят именно таким образом;
'/\.txt$/i' — соответствует строке, хранящей имя файла с расширением txt;
390
/^$/s — сопоставимо только с пустой строкой, потому что говорит: "сразу после начала строки идет ее конец".

Оператор альтернативы
Другие возможности PCRE
Замена совпадений
Разбиение по регулярному выражению
Экранирование символов
Примеры использования регулярных выражений
Преобразование адресов e-mail
Преобразование гиперссылок

Группирующие скобки
'#^(\w:|\\\\|/)#'

"Карманы"

<?php ## Простейший разбор даты   
$str = " 15-16/2000"; // к примеру 
$re = '{^\s*(# начало строки (\d+) # день 
	\s* [[:punct:]] \s*            # разделитель       
	(\d+)                          # месяц         
	\s* [[:punct:]] \s*            # разделитель      
	 (\d+)                         # год     
	)\s*$                  # конец строки   
     }xs';   
	// Разбиваем строку на куски при помощи preg_match()   
	preg_match($re, $str, $matches) or die("Not a date: $str");   
	// Теперь разбираемся с карманами   
	echo "Дата без пробелов: '$matches[1]' <br />";   
	echo "День: $matches[2] <br />";  
	echo "Месяц: $matches[3] <br />";   
	echo "Год: $matches[4] <br />"; 
	?>

Использование карманов в функции замены

<?php ## Замена по шаблону   
$text = htmlspecialchars(file_get_contents(__FILE__));   
$html = preg_replace('/(\$[a-z]\w*)/is', '<b>$1</b>', $text);   
echo "<pre>$html</pre>"; 
?>
Использование карманов в функции сопоставления </pre>

<em>В  строке  есть  подстрока,  обрамленная  какими-то  HTML-тегами  (например,  <b>  или  <pre>),  но  неизвестно,  какими. Требуется  поместить  эту  подстроку  в  карман,  чтобы    в  дальнейшем  с  ней  работать.  Разумеется,  закрывающий  тег  должен  соответствовать  открывающему, например, к тегу <b> парный — </b>, а к <pre> — 

.
Задача решается с помощью такого регулярного выражения:

|<(\w+) [^>]* > (.*?) </\1>|xs 

<?php ## Обратные ссылки   
$str = "Hello, this <b>word</b> is bold!";
$re = '|<(\w+) [^>]* > (.*?) </\1>|xs';   
preg_match($re, $str, $matches) or die("Нет тегов.");   
echo htmlspecialchars("'$matches[2]' обрамлено тегом '$matches[1]'"); 
?> 

Игнорирование карманов

<?php ## Игнорирование карманов   
$str = "2015-12-15";   
$re = '|^(?:\d{4})-(?:\d{2})-(\d{2})$|';   
preg_match($re, $str, $matches) or die("Соответствие не найдено");   
echo htmlspecialchars("День: ".$matches[1]); 
?> 

Именованные карманы

<?php ## Именование карманов   
$str = "2015-12-15";   
$re = "|^(?<year>\d{4})-(?<month>\d{2})-(?'day'\d{2})$|";   
preg_match($re, $str, $matches) or die("Соответствие не найдено");   
echo "День: "  . $matches['day']   . "<br />";   
echo "Месяц: " . $matches['month'] . "<br />";   
echo "Год: "   . $matches['year']  . "<br />"; 
?> 
"Жадность" квантификаторов 
<?php ## "Жадные" квантификаторы   
$str = "Hello, this <b>word</b> is <b>bold</b>!";   
$re = '|<(\w+) [^>]* > (.*) </\1>|xs';   
preg_match($re, $str, $matches) or die("Нет тегов.");   
echo htmlspecialchars("'$matches[2]' обрамлено тегом '$matches[1]'"); 
?>
<?php ## Сравнение "жадных" и "ленивых" квантификаторов   
$str = '[b]жирный текст [b]а тут еще жирнее[/b] вернулись[/b]';   
$to  = '<b>$1</b>';  
 $re1 = '|\[b\] (.*)  \[/b\]|ixs';   
$re2 = '|\[b\] (.*?) \[/b\]|ixs';  
$result = preg_replace($re1, $to, $str);   
echo "Жадная версия: ".htmlspecialchars($result)."<br />";   
$result = preg_replace($re2, $to, $str);   
echo "Ленивая версия: ".htmlspecialchars($result)."<br />"; 
?> 
Рекуррентные структуры
Модификаторы
Модификатор /i: игнорирование регистра
Модификатор /x: пропуск пробелов и комментариев

Модификатор /m: многострочность

<?php ## Многострочность   
$str = file_get_contents(__FILE__);   
$str = preg_replace('/^/m', "\t", $str);   
echo "<pre>".htmlspecialchars($str)."</pre>"; 
?>

Незахватывающий поиск

Негативный просмотр вперед

Позитивный просмотр назад

Например, рассмотрим регулярное выражение |(\S+)(?=\s*)|. Оно совпадет со словом, сразу после которого идет закрывающий HTML-тег (возможно, с промежуточными пробелами). При этом ни сам тег, ни пробелы в совпадение не войдут.

Негативный просмотр назад

Другие возможности PCRE
При желании вы можете прочитать о них в документации Perl (PCRE — это ведь регулярные выражения Perl), а также на сайте PHP (доступен перевод на русский язык): http://ru.php.net/manual/ru/ pcre.pattern.syntax.php.

Функции PHP

<?php
  ## Использование PREG_OFFSET_CAPTURE   
$st = '<b>жирный текст</b>';   
$re = '|<(\w+).*?>(.*?)</\1>|s';   
preg_match($re, $st, $p, PREG_OFFSET_CAPTURE);   
echo "<pre>"; 
print_r($p);
 echo "</pre>";   
?>

Модификатор /s: (однострочный поиск)
Модификатор /e: выполнение PHP-программы при замене

http://fkn.ktu10.com/?q=node/7716
Функции и области видимости. Генераторы
Итераторы" + "Отражения
Документирование
Осваиваем Linux (и LAMP в частности)

JQuery -- как библиотека для программирования браузерных сценариев Исходный код примеров можно получить тут (link is external), клонировав данный репозиторий на ваш компьютер.
Первая CMS -- вникаем в существующий код и выполняем практические задания

vedro-compota's picture

такие записи лучше делать в блоге

_____________
матфак вгу и остальная классика =)