Регулярные выражения: как это понимать
Занимаясь IT уже более 10 лет, твердо уяснил: следует не гоняться за модным, а постигать вечное. Лучше тратить время не на поиск «классненьких программок», а на освоение фундаментальных концепций, таких как сетевые протоколы, классические языки программирования вроде C, XML, SQL, ну и, конечно же, regexp — синтаксис регулярных выражений. О последнем и пойдет речь под катом.
Регулярные выражения нужны для поиска в тексте по шаблону и нет ничего лучше для этой цели если, конечно, знать как они устроены. Выглядят они отталкивающе, например, вот это
— выражение для проверки корректности электронного адреса. Аж глаза режет от слэшей, решеток, скобок и т.п. Хочется глядя на такое безобразие употреблять не регулярные выражения, а не очень приличные.
И все-таки, регэкспы — они как люди-дикари, т.е. на лицо ужасные, добрые внутри. Кто с ними подружился — получает мощное преимущество в кодописании. Здесь можно было бы сказать: «А посему — 74.125.87.106/ в помощь!». Однако материалов действительно проясняющих запутанную тему регэкспов, в сети не так уж и много. Один из лучших — статья с сайта IBM (на русском). Неплохо изложена тема и в Википедии. В данном же топике я попробую изложить самые основы, которые можно освоить за одно прочтение. Желающие углубиться смогут потом перейти по указанным ссылкам.
Первое, что бросается в глаза в регэкспах — обилие вспомогательных (не буквенно-цифровых) символов. Люди, которые берутся объяснять эту тему, сразу же начинают перечислять и описывать, все эти скобки, палки, решетки и их назначение. А я бы начал как раз с того, чтобы показать, что в простейшем случае можно искать в тексте просто сочетания букв, например:
Здесь мы пропускаем фразу «To be or not to be» через процессор регулярных выражений — утилиту grep. Само выражение задано после ключа -e (сочетание 'be'). Ключ -o указывает, что на экран нужно выводить только фрагменты текста, соответствующие шаблону. Без него выводились бы строки, в которых встречается шаблон.
Обратите внимание, что для экспериментов выбрана англоязычная фраза. С национальными алфавитами работают не все реализации регэкспов и эту тему мы затрагивать здесь не будем.
Самое время освоить первый служебный знак регэкспов — '.' (точка). Она означает «здесь может находиться любой знак (буква, цифра, знак препинания и т.п.)».
В этих примерах рассматриваются шаблоны 'b.', 'b..', 'b...'. В первом случае нашлось два вхождения шаблона в фразе: «To be or not to be». Во втором — одно. Почему? Потому что второе be идет в конце предложения и третьего знака после него просто нет. На экран программа вывела не просто be, а be и пробел, т.е. букву b и любые два знака после нее. В третьем случае вывелось 'be o' «To be or not to be» (буква b и любые три знака после нее).
Рассмотрим еще два знака, участвующих в любой реализации regexp: ^ и $. Почему выбраны именно они — сказать трудно. Просто нужно запомнить, что означают они начало и конец рассматриваемого текста:
То есть в первом случае нужно вывести 9 знаков от начала текста, во втором — от конца.
На этом закончу краткий экскурс, чтобы дальнейшими усложнениями не отбить у читателей аппетит. Вот теперь действительно: «Google в помощь»!
Регулярные выражения нужны для поиска в тексте по шаблону и нет ничего лучше для этой цели если, конечно, знать как они устроены. Выглядят они отталкивающе, например, вот это
^((?>[a-zA-Z\d!#$%&'*+\-/=?^_`{|}~]+\x20*|"((?=[\x01-\x7f])[^"\\]|\\[\x01-\x7f])*"\x20*)*(?<angle><))?((?!\.)(?>\.?[a-zA-Z\d!#$%&'*+\-/=?^_`{|}~]+)+|"((?=[\x01-\x7f])[^"\\]|\\[\x01-\x7f])*")@(((?!-)[a-zA-Z\d\-]+(?<!-)\.)+[a-zA-Z]{2,}|\[(((?(?<!\[)\.)(25[0-5]|2[0-4]\d|[01]?\d?\d)){4}|[a-zA-Z\d\-]*[a-zA-Z\d]: ((?=[\x01-\x7f])[^\\\[\]]|\\[\x01-\x7f])+)\])(?(angle)>)$
— выражение для проверки корректности электронного адреса. Аж глаза режет от слэшей, решеток, скобок и т.п. Хочется глядя на такое безобразие употреблять не регулярные выражения, а не очень приличные.
И все-таки, регэкспы — они как люди-дикари, т.е. на лицо ужасные, добрые внутри. Кто с ними подружился — получает мощное преимущество в кодописании. Здесь можно было бы сказать: «А посему — 74.125.87.106/ в помощь!». Однако материалов действительно проясняющих запутанную тему регэкспов, в сети не так уж и много. Один из лучших — статья с сайта IBM (на русском). Неплохо изложена тема и в Википедии. В данном же топике я попробую изложить самые основы, которые можно освоить за одно прочтение. Желающие углубиться смогут потом перейти по указанным ссылкам.
Первое, что бросается в глаза в регэкспах — обилие вспомогательных (не буквенно-цифровых) символов. Люди, которые берутся объяснять эту тему, сразу же начинают перечислять и описывать, все эти скобки, палки, решетки и их назначение. А я бы начал как раз с того, чтобы показать, что в простейшем случае можно искать в тексте просто сочетания букв, например:
echo "To be or not to be" | grep -o -e 'be'
be
be
Здесь мы пропускаем фразу «To be or not to be» через процессор регулярных выражений — утилиту grep. Само выражение задано после ключа -e (сочетание 'be'). Ключ -o указывает, что на экран нужно выводить только фрагменты текста, соответствующие шаблону. Без него выводились бы строки, в которых встречается шаблон.
Обратите внимание, что для экспериментов выбрана англоязычная фраза. С национальными алфавитами работают не все реализации регэкспов и эту тему мы затрагивать здесь не будем.
Самое время освоить первый служебный знак регэкспов — '.' (точка). Она означает «здесь может находиться любой знак (буква, цифра, знак препинания и т.п.)».
echo "To be or not to be" | grep -o -e 'b.'с
be
be
echo "To be or not to be" | grep -o -e 'b..'
be
echo "To be or not to be" | grep -o -e 'b...'
be o
В этих примерах рассматриваются шаблоны 'b.', 'b..', 'b...'. В первом случае нашлось два вхождения шаблона в фразе: «To be or not to be». Во втором — одно. Почему? Потому что второе be идет в конце предложения и третьего знака после него просто нет. На экран программа вывела не просто be, а be и пробел, т.е. букву b и любые два знака после нее. В третьем случае вывелось 'be o' «To be or not to be» (буква b и любые три знака после нее).
Рассмотрим еще два знака, участвующих в любой реализации regexp: ^ и $. Почему выбраны именно они — сказать трудно. Просто нужно запомнить, что означают они начало и конец рассматриваемого текста:
echo "To be or not to be" | grep -o -e '^.........'
To be or
echo "To be or not to be" | grep -o -e '.........$'
not to be
То есть в первом случае нужно вывести 9 знаков от начала текста, во втором — от конца.
На этом закончу краткий экскурс, чтобы дальнейшими усложнениями не отбить у читателей аппетит. Вот теперь действительно: «Google в помощь»!
Комментарии (5)
RSS свернуть / развернутьСо второго прочтения топика что-то стало проясняться
Спасибо тебе автор!
Gangsta
базы данных, поэтому вьехал в текст с первого прочтения.
Доступно и нонятно. Класс !
Markony
Sergei_T
yababay
Sergei_T
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.