Авто   Интересная история   Искусство   Карьера   Мастер   Недвижимость   Оружие   Подольск   Реклама   «Деловой Подольск»  
Содержание   А Б В Г Д Е Ж З И К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Э Ю Я

Регулярные выражения. Часть вторая

После изучения основ работы, стоит перейти к практическому применению регулярных выражений. Но если посмотреть на большинство регулярных выражений с теми знаниями, которые у вас есть, получится, что они до сих пор являются набором значков, правда, некотор

После изучения основ работы, стоит перейти к практическому применению регулярных выражений. Но если посмотреть на большинство регулярных выражений с теми знаниями, которые у вас есть, получится, что они до сих пор являются набором значков, правда, некоторые из них уже узнаваемы. В этой части я буду, базируясь на том, что рассказал в предыдущей главе, расширять ваш кругозор.


Спецсимволы.
Как показать невидимое? Как указать, например, что в условии поиска присутствует пробел? Наверное. многие догадываются, что для того, чтобы показать невидимое, надо сделать его видимым, т.е. ввести какой-то символ, набор символов, которые будут интерпретироваться, как невидимые. Вот с этими знаниями мы и пришли к изучению спецсимволов в регулярных выражениях.


s – если вы в условии поиска поставите друг за другом символ обратного слеша, а после него сразу букву s, то таким образом вы опишите либо пробел, либо символ табуляции. Конечно в условии поиска можно поставить пробел так, как вы его обычно ставите на письме, но запись [a-zs] будет намного понятнее и читабельней чем [a-z ], с первого взгляда видно, что в первый символьный класс входит пробел, а вот со вторым символьным классом надо присмотреться, а так как регулярные выражения итак представляют для многих набор значков, то пропустить пробел, поставленный таким образом будет очень просто.
Внимательно используйте этот спецсимвол, так в дополнении к тому, что он совпадает с пробелом и табулятором, он совпадет также с символом новой строки.


S – скажу просто, что в своем большинстве это видимые символы, т.е. все, что не совпадает с s


w – спецсимвол, который призван заменить целый символьный класс, в него входят все символы, которые могут входить в слово, обычно это [a-zA-Z_], хотя много может зависеть от установленной локали, поддержки юникода и т.д.


W – все что не входит в определение w. либо [^a-zA-Z_]


d – все цифры т.е. уже известный вам символьный класс [0–9]


D – все, что не является цифрой


Как видите, часто спецсимволы описывают какие-то частоиспользуемые множества символов, которые используются программистами каждый день, но эти множества имеют границы, т.е. либо цифры, либо буквы и подчеркивание, либо невидимые символы, но как описать все символы? Просто! Надо поставить точку!


А вы спросите тогда, а что делать, если надо описать именно точку, а не все символы? Поставьте перед точкой обратный слеш: .
Но вы не унимаетесь и хотите знать, что делать если вы ищите в тексте обратный слеш, после которого идет точка. Все просто, как видите, обратный слеш, входит практически в любой спецсимвол, а так же нужен, чтобы из спецсимвола сделать литерал, значит этот обратный слеш, сам по себе является спецсимволом, и для того, чтобы превратить его в литерал, надо следовать тем же правилам, которые были использованы при превращении точки из спецсимвола в литерал, а именно перед спецсимволом, поставить еще один спецсимвол, чтобы больше не выдумывать никаких специсимволов, решили пользоваться тем же слешем. Итак чтобы поставить обратный слеш в виде литерала в условии поиска,надо его удвоить вот так: \
Аналогично, чтобы поставить два обратных слеша их надо тоже удвоить вот так: \\


Альтернативы
Быть или не быть... Извечная альтернатива! После прочтения этой части, вы сможете самостоятельно записать гамлетовскую альтернативу при помощи регулярных выражений. Сначала как всегда разберемся с данными, которые надо обработать. У Гамлета был выбор между быть (be) и не быть (not to be). В любом случае он получал на выходе какое-то решение, которое равнялось true :) Чтобы описать условие выбора при помощи регулярных выражений надо сначала определиться между чем и чем выбирать будем. В случае Гамлета мы выбираем между группами литералов, одна группа состоит из двух литералов идущих друг за другом b и e, вторая группа состоит из девяти литералов идущих друг за другом:
n, o, t, s, t, o, s, b, e
Понятно, что s представляет собой один пробел. Я, кажется, употребил новое слово, на которое вы не обратили свое внимание: группа литералов. Группа литералов – последовательность символов, которые описаны либо символьными классами, либо собственно литералами. Группу литералов описывают в круглых скобках, они же сохраняют совпавшую группу литералов в специальных переменных, о которых я писал в предыдущей статье. Вот примеры групп литералов:
(be)
(notstosbe)
Теперь вернемся к выбору из двух групп литералов:
(be)|(notstosbe)
вот эта палочка | между группами литералов и есть условие выбора, читается как 'или'. Теперь представьте, что ответ Гамлета обрабатывает компьютер, которому известно, что может быть только два ответа либо «быть» либо «не быть». Все остальные ответы просто не принимаются за ответы как таковые. Пишем регулярное выражение проверки ответов Гамлета:
preg_match(«/^(be)|(notstosbe)$/», $alternate, $answer);
Регулярное выражение совпадет в случае
1. если $alternate равно “be”
2. если $alternate равно “not to be”


Вначале объяснения я вопрошал, между чем выбирать будем. Думаю, самое время разобраться, между чем вообще можно выбирать. Выбирать можно между литералами и между группами литералов. Как уже было сказано, группы литералов объединяются круглыми скобками, если надо выбрать между одиночными литералами, то два литерала между, которым стоит вертикальная черта, надо сгруппировать скобками.
Пример выбора из двух литералов:
s(o|u)n совпадет как с son, так и с sun.
Пример выбора из двух групп литералов:
(son)|(sun) аналогично совпадет с son и с sun


В случае с выбором между группами литералов, либо между одиночными литералами, литералы объединяются при помощи круглых скобок, но в первой статье в части Запомнить все, я сказал, что все, что заключается в круглые скобки, запоминается в специальных переменных. Запоминается, значит использует ресурс «память». Что делать, если нам не нужно запоминать выделенные группы литералов, на надо их сгруппировать? Надо заставить скобки не запоминать! Делается это при помощи последовательности ?: вот так:
(?:be)|(?:notstosbe)
теперь ни группа литералов “be” ни группа литералов “not to be” не будут заноситься в переменные 1, 2 (Perl $1, $2), но зато будут отлично группироваться.


Понятно, что, если надо поставить литерал "|", то надо перед ним поставить спецсимвол, который будет обозначать, что в данном случае вертикальная черта является литералом. Этим спецсимволом служит обратный слеш:
|

Примеры

1.
У администратора есть список пользователей, которые генерирует программа, либо утилита, генерирует она этот список в формате:
фамилия имя отчество
фамилия и о
фамилия и.о.


Как всегда боссу требуется какая-то статистика, но его абсолютно не интересуют ни имена ни отчества, ему нужна фамилия и инициалы в виде:
фамилия ио


Надо что-то делать... я сделал это вот так (цикл перебора по всем строкам, которые генерирует утилита, напишете сами):
preg_match(«/([^s]+)s+([^s.])[^s.]*(?:s|.)([^s.])[^s.]*/»,$income_str,$out_arr);
print_r($out_arr);


Сначала разберемся с данными, которые поступают на вход, чтобы регулярное выражение срабатывало в 100% случаев. Данные не надо проверять на совпадение с условием, так данные хранящиеся в системе прошли эту проверку при их вводе. И фамилия и имя и отчество могут состоять из любых символов, так как мы не знаем, какие символы разрешает система, и какие символы ввел в систему пользователь, но достоверно известно, что фамилия отделена от имени пробелом, имя и отчество могут быть полными, могут сотоять из одной буквы-сокращения, могут быть разделены пробелом, либо после каждой буквы стоит точка.


Если вы научитесь сами сотавлять подобные описания данных, по которым вам нужно проводить поиск, то большая часть вашей работы сделана, потому что осталось только записать предыдущее предложение на языке регулярных выражений:
[^s] — любой символ, который не является пробелом! включая символ новой строки, можно было написать S без крышки вначале символьного класса, но это на любителя.
[^s]+ — минимум один символ, который не является пробелом, т.е. фамилию мы уже описали.
s+ — минимум один пробел между фамилией и именем


Для обозначения имени исползуется несколько способов:
а. полное имя и после него пробел
б. первая буква имени и после него пробел
в. первая буква имени и после него точка
Что надо искать? Все, после пробела между фамилией и именем и до следующего пробела, либо точки, причем имя или его сокращение состоит минимум из одной буквы.
[^s] — все что не пробел, первый обязательный символ имени (сокращения)
[^s.] — все что не пробел и не точка, в символьном классе точка — литерал
[^s.]* — в случае полного имени, это будет означать, что надо найти все, что не точка и не пробел и идет после обязательного первого символа имени, который мы описали выше


Получается, что имя мы описали вот такой конструкцией:
[^s.][^s.]*
но первую букву имени (даже если там сокращение) по условию задачи надо запомнить:
([^s.])[^s.]*


Что идет после имени? в любом случае там идет либо пробел, либо точка. Значит нужно пройти этот участок так, чтобы выполнилось условие выбора из двух символов:
(s|.) — выбор между двумя литералами осуществляется путем группировки их в круглые скобки и написания между литералами вертикальной черты. Если в строке гарантировано будет только один пробел, то можно так и оставить, если вы не уверены, поставьте символ '+' после s:
(s+|.)


Вам нужно запоминать что стояло между фамилией и отчеством, пробел или точка? Мне нет! Поэтому из сохраняющих и группирующих скобок делаем только группирующие:
(?:s|.)
А теперь посмотрите на отчество, с точки зрения регулярных выражений, символы, из которых оно составлено, подчиняется тем же правилам, что и имя, поэтому описание следующей части регулярного выражения и до конца смотрите выше.

Сергей Колесниченко

23/01/2006  
дополнительно
как можно оптимизировать PHP-Nuke
Отрисовка связанного дерева с помощью XSLT - как с умом использовать XSLT и XPath
Регулярные выражения.
Когда и почему не следует использовать регулярные выражения
Регулярные выражения. Часть 3
Шерлок Холмс спешит на помощь вебпрограммисту или регулярные выражения на пальцах
Регулярные выражения. 1
Сверхдинамичные веб-интерфейсы
юю
юю
back home top
название
анонс:
текст:
примечание:
отправитель:   mail:

Для публикации принимаются интересные и полезные статьи, которые наверняка заинтересуют жителей города Подольска и Подольского района. Статьи размещаются в по тематическом разделам журнала: «Недвижимость», «Авто-Подольск», «История Подольска и его окрестностей», «Искусство», «Карьера», «Реклама», «Оружие», «Деловой Подольск» Наиболее интересные материалы публикуются в электронных изданиях и рассылках группы «podolsk.biz».

Подольск Адреса История Подольские Форумы Объявления Справочник Фото Журнал
Подольское городское информационное агенство podolsk.biz размещение сайтов о городе Подольск и Подольском районе. имя вида название.podolsk.biz, почтовые адреса вида название@podolsk.biz
Подольское агенство podolsk.biz

Отдел рекламы 8903 1347521

поиск по Подольску



Подольск   карта сайта   Реклама на «podolsk.biz»