Регулярные выражения (PHP). PHP: регулярные выражения, примеры
Насколько велик и многообразен мир информации, настолько же стремительно он расширяется и развивается. Любое решение - всего лишь момент в общем процессе движения. Знания и опыт дают возможность понимать процесс достижения цели, но никогда - не результат ее достижения. Сомнительно, что в обозримом будущем вообще можно говорить о результате, но очень важно, что процесс стремления к нему представляет существенный и объективно-необходимый процесс.
«Желание и/или большие деньги» не создают алгоритм, способный на то, что естественно и «бесплатно» делает человек, особенно когда он не задумывается над тем, что именно он делает. Во всяком положении информационной задачи есть как минимум одно белое пятно, но за ним, обычно сразу, видны другие чистые пятна, и вовсе не обязательно, что все они белых цветов.
Интернет технологии существенно упростили доступ к информации, но вопрос - как наложить на имеющееся желаемое - не упростился, а приобрел новые «объемы» работ. И хотя на PHP регулярные выражения пробел явно не исчерпают, они есть существенный шаг вперед.
Простые функции + алгоритм = шаблон
Предлагая регулярные выражения, PHP существенно уменьшает содержание алгоритма, но обычные функции поиска/замены и алгоритмы обработки найденного не потеряли своего значения. Новые идеи не предвещают информационную революцию. Максимум, на который можно рассчитывать - компактный код и рост умения разработчика правильно формулировать поисковый запрос.
Следует знать и применять на PHP регулярные выражения. Примеры убедительны и эффективны. Но следует отдавать отчет, что с появлением нового механизма поиска центр тяжести переместился в шаблон - своеобразный механизм, хотя по сути заменяющий множество простых функций поиска, условий, циклов, других операторов.
Иметь:
- качественный и современный инструмент – это хорошо;
- видеть и использовать опыт коллег –это важно;
- совмещать реальную действительность и виртуальные идеи – гарантия успеха.
Достижение знания, как надо было понимать задачу, чтобы ее решить, чаще имеет большее значение, чем конкретный результат.
Регулярные выражения в PHP представлены несколькими функциями в синтаксисе языка и множеством полезных примеров в интернете. Ввиду специфики синтаксиса языка варианты применения ограничены только воображением разработчика, однако слеует иметь в виду, что далеко не все шаблоны будут работать. Средствами PHP проверка регулярных выражений имеет существенное значение.
Простой поиск символа (строки)
Символ - это не всегда один байт, и часто символ, как элементарный сигнал, несет точный смысл дополнительно. Кодировка определяет видимые символы в коде по разному. Символ может иметь несколько вариантов: "$" = "USD" = "у.е.", ... - это точный смысл, что где-то что-то, но не обязательно рядом, связано с валютой. Однако точный смысл может лежать и в переменной PHP, которая всегда начинается с символа "$", но не может начинаться с "USD" и "у.е.".
В программах символом может быть имя функции (строка) в контексте: распознать и исполнить - это из области динамичного объектно-ориентированного программирования, когда конструкции, функции, регулярные выражения PHP используются непосредственно для принятия решений. Найденный символ «исполняется», то есть сам собой определяет, что нужно делать в том месте, в котором он найден, и так, как он это «сам сочтет» нужным.
Искать просто символ/строку - не такое простое занятие, и чем больше в символе информации, тем лучше. Не всегда нужно найти десяток лучших цен на продукты питания, выбрать вкусные рецепты праздничного торта или определиться с подрядчиком на навесной потолок.
Часто приходится оптимизировать простые алгоритмы с не простой информационной арифметикой или в сложных условиях, когда искомый символ нужно выбрать из базы данных, а строку, в которой его следует найти, - в сотне сайтов. При этом цена выбора символа равна времени выборки из базы данных, а цена того, где искать – времени поиска пресловутой сотни сайтов.
Одинокий символ - это не фраза и не несколько фраз, он может находиться где угодно и быть сколь угодно малым. Как определить, что именно найденное есть искомое?
Пример: поиск цены
Просто найти в тексте символ "$" - мало. Проверить, что перед ним стоит цифра, тоже не всегда достаточно. Если предусмотреть точку или цифру перед символом "$", это гарантия, что цены, у которых денежные символы стоят впереди, не будут учтены. Будут также пропущены цены, в которых вообще не указана денежная единица, но на странице есть на нее явное указание.
В общем, решение поставленной задачи обычным образом раздует алгоритм до неузнаваемости и займет много времени. Между тем, используя регулярное выражение, число PHP найдет без проблем.
$cContents = preg_match_all("/[0-9]+([\$]|usd|у\.е\.|уе){1}/i";
"look e-mail - 2usd; <br/>" ;
"find e-mail - 2у.е.; <br/>" ;
"work e-mail - уе2; <br/>" ;
"check e-mail - $13", $aResult);
. '; ' . implode(',', $aResult[0]) . '<br/>'.
Даст ответ: "2; 2usd,2у.е.", но не найдет ничего в строке: "check e-mail - $13".
Предусмотрев в шаблоне наличие символа спереди или сзади, можно быстро достигнуть цели в подавляющем большинстве случаев.
$cContents = preg_match_all("/([0-9]+([\$]|usd|у\.е\.|уе){1})|(([$]|usd|у\.е\.|уе){1}[0-9]+)/i";
"look e-mail - 2usd; <br/>";
"find e-mail - 2у.е.; <br/>";
"work e-mail - уе2; <br/>";
"check e-mail - $13", $aResult);
. '; ' . implode(',', $aResult[0]) . '<br/>'.
Результат: "4; 2usd,2у.е.,уе2,$13".
О непредусмотренной логике
Регулярные выражения PHP предлагает, как и другие инструментальные средства, но совершенно не обязательно их применять по его правилам или использовать другие строчные функции предусмотренным синтаксисом образом.
Можно перед началом поиска превратить искомое в массив, а место, где будет осуществлен поиск, разбить на составляющие по предварительному критерию. Простая пара функций explode() и implode() часто упрощает и ускоряет решение.
Например, в результате предварительных работ сформирован массив строк (данных) по району о том, сколько картошки собрала каждая деревня: указано ИмяДеревня и собранный объем, а если в деревне работает несколько предприятий, то в строку массива идет ИмяДеревня.ИмяПредприятие и значение через ";" и так по всем предприятиям. Посчитать общий объем собранного в данном случае не представится возможным, но если сделать impode(";", $aResult), будет одна длинная строка, в которой пары - ИмяДеревня/ИмяДеревня.ИмяПредприятие – собраный объем - будут перечислены через ";". Сделав обратное на полученном, explode(";", $aResult) - массив всех, кто собирал и сколько он собрал, затем, удалив из строк все нецифровые символы, имеем только цифры, сумма которых и будет общим объемом собранного.
В данном примере регулярные выражения на PHP позволяют вовсе не искать лишнее, они просто и доступно извлекают нужные цифровые значения. Быстро и эффективно, какими бы длинными ни были имена деревень и предприятий. Это решение не идеал, но оно показывает, что далеко не всегда следует следовать правилам. Часто можно достигнуть желаемого необычным образом.
Абстрагируясь от технической стороны, от кодировки
Синтаксис алгоритма не говорит о том, как он выглядит на самом деле. Но, обеспечив одинаковую кодировку страницы, скрипта и строк (которая ищется и в которой происходит поиск), можно погрузиться в задачу вне ее технической стороны.
Нужно не только знать, что искать, но и где это делать, когда, в каком количестве, на что менять и каким образом. Формально регулярные выражения PHP выполнены как законченный собственный полнофункциональный механизм, однако по многим причинам реализация его аналогов в разных языках отличается. По общему правилу, прежде чем переносить тот или иной шаблон в ту или иную инструментальную среду для решения конкретной задачи, необходимо провести качественную адаптацию, выполнить проверку на всех возможных вариантах исходных данных.
Даже если используется собственный опыт разработки на PHP, регулярные выражения, примеры, шаблоны и конструкции требуют пристальной проверки. Динамично меняется функционал языка, его синтаксис и среда исполнения.
Структура и содержание шаблона
То, что было ранее написано в виде комбинации функций поиска, условных операторов, операций замены, вставки, удаления, заключается в одну строку символов по определенным правилам – шаблон регулярного выражения. Фактически значительный объем кодируется строго определенным образом и исполняется по конкретным правилам.
Равно как нельзя заняться отладкой любого оператора языка, так нельзя выполнить отладку шаблона регулярного выражения, этот процесс можно только эмулировать. По общему правилу принят вариант: работает - не работает. Синтаксис очень прост, хотя его восприятие, особенно в начале работы, очень затруднительно.
Пример простого выражения
В простом варианте шаблон совпадает со строкой:
$cContents = preg_match("/asdf/i", "asdf", $aResult) . '; ' . implode(',', $aResult).
Результат будет "1; asdf", поскольку функция заканчивает свою работу на первом же встреченном совпадении шаблона. Результат будет таким же, если искать в строке "aaaasdf" и в строке "zzzasdfvvv". Если указать первый и/или последний символ, то итог будет однозначным:
$cContents = preg_match("/^asdf/i", "asdf", $aResult) . '; ' . implode(',', $aResult) . '<br/>';
$cContents .= preg_match("/asdf$/", "asdf", $aResult) . '; ' . implode(',', $aResult) . '<br/>'.
Результат будет:1; asdf1; asdf.
Символы "^" и "$" указывают, с чего начинается шаблон и чем заканчивается. Результат функции preg_match – количество совпадений, оно может быть 0, 1 или false, если обнаружена ошибка. В третий параметр – массив - помещается единственный найденный элемент. В случае использования функции preg_match_all() поиск продолжается до конца строки.
$cContents = preg_match("/asdf/i", "asdf123asdf456asdf789", $aResult) . '; ' . implode(',', $aResult) . '<br/>';
$cContents .= preg_match_all("/asdf/i", "asdf123asdf456asdf789", $aResult) . '; ' . implode(',', $aResult[0]) . '<br/>'.
Результат:
1; asdf
3; asdf,asdf,asdf.
Если не использовать специальных указаний, то каждый символ определяет себя и свое место, вне зависимости от кодировки строки и кодировки шаблона. Программист обязан позаботиться, чтобы кодировки этих элементов были корректными по отношению друг другу и кодировке странице.
Функции PHP для работы с регулярными выражениями
Регулярные выражения на PHP представляют собой строки символов, записанные определенным образом. Обычно, по аналогии с другими языками программирования, они записываются в символах "/" ... "/" и помещаются в кавычки, в зависимости от алгоритма можно использовать одинарные и двойные.
Основная функция php preg match регулярные выражения использует как совпадение шаблона и останавливается при первом его нахождении, ее вариант с суффиксом _all ищет все совпадения и выдает массив таковых. Функция preg replace производит замену каждого найденного совпадения шаблона, она может работать с массивами, позволяя проектировать поиск и выполнять замену по множеству вариантов.
Интересные варианты работы с регулярными выражениями можно разработать при помощи функции preg_replace_callback, которая принимает не текст для замены, а имя функции, которая будет выполнять такую замену. Помимо практического значения здесь можно реализовать механизмы проверки шаблонов, что в разработке и отладке последних играет существенную роль.
Сфера применения регулярных выражений
Поскольку языки гипертекста представляют собой формализованную информацию, в большей мере именно они являются исходным материалом. Разработано большое количество шаблонов и конструкций, позволяющих эффективно обрабатывать большие объемы информации. Значительную часть такой работы выполняют механизмы, встроенные в различные системы управления сайтами (CMS).
Не удивительно, что многие CMS стали стандартами де-факто для построения сайтов, и, будучи сопровождаемыми (обновляемыми) компаниями-разработчиками, они не делают необходимым выполнять разработку шаблонов собственными силами. Однако за пределами таких систем иметь опыт работы с регулярными выражениями очень полезно.
Регулярные выражения и реальная информация
Важная область применения регулярных выражений на PHP сформирована появлением библиотек PHPOffice. Работа с документами и электронными таблицами всегда имела и имеет важное значение, а стандарт OOXML позволил не только разбирать реальные документы, но и формировать их программно.
Благодаря развитию языков гипертекста и PHP в частности, появилась реальная возможность автоматизировать "производство" документов "стандартной формы", например, счетов на оплату, отчетов, бизнес-планов и других информационных объектов, структура и содержимое которых реально поддается формализации и автоматизации.
В связи с применением для описания языка OOXML процесс разработки регулярных выражений имеет существенные отличия от традиционной работы с языками разметки HTML и CSS в первую очередь. Реальный документ, кроме разметки и кроме собственно контента имеет множество деталей. Например, документ, созданный автоматически программой, будет иметь строгое и точное содержание. Документ, сформированный человеком или им обработанный, будет иметь содержание, расписанное по множеству тегов. Любая работа с документом приводит к тому, что семантика его может оставаться одной, но расписанной внутри по различному количеству разных конструкций.
Естественная информация и ситуация
Человека всегда интересует решение задачи, постановка которой есть информация и, в результате, будет дана так же информация. Представив постановку задачи в виде документа, человек получает определенную семантику, которая в ходе уточнения специалистами (внесение изменений, уточнение формулировок, удаление, редактирование) приводит не только ко множеству вариантов одного документа, но и к его версиям с различным содержанием.
В частности, задача, поставленная фразой "Решить квадратно уранение", после редактирования не будет выглядеть так: "Решить квадратное уравнение". Если была исправлена сначала первая ошибка, а потом вторая, то естественная информация в стиле OOXML может иметь вид: "[Решить][ ] [квадратно][е] [ ] [ура][в][нение]", но это вовсе не гарантия, что именно так задача будет выглядеть в тегах OOXML (квадратные скобки эмулируют скобки тегов).
Собрать воедино информацию можно легко после каждого процесса редактирования задачи, но каждый раз эта процедура будет выполняться по различному алгоритму. Регулярные выражения, как своего рода инструмент формализации информационных задач, стали, по сути, тропинкой от формальных гипертекстовых структур к естественной информации.