LXF139:regexp

Материал из Linuxformat.

Перейти к: навигация, поиск
Hardcore Linux Проверьте себя на крутом проекте для продвинутых пользователей

Содержание

Про­грам­ми­ру­ем: регeкспы

Они не столь и ужас­ны. Нет, прав­да. Грэм Мор­ри­сон ра­зо­бла­ча­ет од­ну из по­след­них хит­ро­стей вре­мен ко­манд­ной стро­ки.

Для боль­шин­ст­ва из нас ре­гу­ляр­ные вы­ра­жения – ре­гек­спы – за­га­доч­ны, как еги­пет­ские ие­рог­ли­фы. При­чуд­ли­вая смесь сим­во­лов, букв и цифр вдруг об­ра­зу­ет все­мо­гу­щее за­кли­нание, пре­вра­щаю­щее свинец в зо­ло­то, а име­на фай­лов – в ка­та­ло­ги. Ре­гек­спы – при­знак про­фес­сио­на­ла, веч­но за­ня­то­го сис­тем­но­го ад­ми­ни­ст­ра­то­ра, не снис­хо­дя­ще­го до по­вто­рения од­но­тип­ных дей­ст­вий, или про­грам­ми­ста, изы­ски­ваю­ще­го фраг­мен­ты ко­да или оп­ти­ми­зи­рую­ще­го код на Perl.

Но ре­гу­ляр­ные вы­ра­жения так­же неве­ро­ят­но по­лез­ны поч­ти всем, в том чис­ле но­вич­кам – для про­стой ра­бо­ты с фай­ла­ми из команд­ной стро­ки, про­сто­го и бы­ст­ро­го по­ис­ка и за­ме­ны или па­кет­ной об­ра­бот­ки. Вы об­на­ру­жи­те, на­при­мер, что мно­гие тек­сто­вые ре­дак­то­ры под­дер­жи­ва­ют ре­гу­ляр­ные вы­ра­жения в боль­шин­ст­ве функ­ций для об­ра­бот­ки фай­лов и по­ис­ка. В Google Code Search ре­гу­ляр­ные вы­ра­жения до­бу­дут вам мил­лио­ны строк пуб­лич­но доступ­но­го ко­да,и да­же в окне «По­иск и За­ме­на» Open­Office.org мож­но поль­зо­вать­ся ре­гу­ляр­ны­ми вы­ра­жения­ми для по­ис­ка по до­ку­мен­там. Пусть вы не хо­ти­те пач­кать ру­ки, изу­чая, как они ра­бо­та­ют – ка­ж­дое вы­ра­жение яв­ля­ет­ся са­мо­доста­точ­ным ре­цеп­том, ко­то­рый лег­ко при­ме­нять в раз­лич­ных си­туа­ци­ях; по­это­му непло­хо за­вес­ти себе биб­лиоте­ку по­лез­ных вы­ра­жений.

В об­щем слу­чае, ре­гу­ляр­ные вы­ра­жения – это тек­сто­вые шаб­ло­ны, спо­соб­ные за­менить неред­ко гро­мозд­кую аль­тер­на­ти­ву при по­ис­ке по стро­кам. На­при­мер, мож­но ис­кать име­на фай­лов, со­дер­жа­щие на­бор цифр, или за­менить все вхо­ж­дения сло­ва «ов­сян­ка» на «мюс­ли» в пап­ке с тек­сто­вы­ми до­ку­мен­та­ми. Они ис­поль­зу­ют­ся в ря­де важней­ших ути­лит команд­ной стро­ки, и да­же в мощ­ных гра­фи­че­­ских при­ло­жениях. Но пре­ж­де чем на­чать их при­ме­нять, раз­бе­рем­ся, где это до­пуска­ет­ся. Во мно­гих мощ­ных ути­ли­тах команд­ной стро­ки, ти­па grep, sed и awk, их мож­но ис­поль­зо­вать «на­пря­мую», хо­тя эти про­грам­мы воспринима­ют сим­во­лы немно­го по-раз­но­му. В команд­ной стро­ке лю­бой из вер­сий Bash' по­сле треть­ей ре­гек­спы в той или иной сте­пени при­менимы во встро­ен­ных ко­ман­дах, та­ких как ls или rm, или в скрип­тах, за­пускае­мых из обо­лоч­ки.

Ра­бо­та с фай­ла­ми

Вам бу­дут уже зна­ко­мы неко­то­рые кон­цеп­ции, ле­жа­щие в осно­ве ре­гу­ляр­ных вы­ра­жений, по­то­му что они на­по­ми­на­ют ис­поль­зо­вание спец­сим­во­лов в мас­ке фай­ла. На­при­мер, по­иск всех фай­лов JPEG с мас­кой *.jpg мож­но клас­си­фи­ци­ро­вать как про­стей­ший тип ре­гу­ляр­но­го вы­ра­жения. Этот при­мер лег­ко рас­ши­рить, за­менив * сим­во­лом ?, означаю­щим не стро­ку сим­во­лов, а один сим­вол:

s picture?.*
# По­иск в Bash фай­лов изо­бра­же­ний с име­на­ми, со­стоя­щи­ми из сло­ва ‘picture’ и еще од­но­го сим­во­ла, и лю­бым рас­ши­ре­ни­ем.

То же спра­вед­ли­во и для ре­гу­ляр­ных вы­ра­жений, в ко­то­рых сим­во­лы для фильт­ров и про­цес­сов ис­поль­зу­ют­ся для по­строения мо­дуль­но­го ре­шения. Спец­сим­во­лы внут­ри ре­гу­ляр­ных вы­ра­жений на­зы­ва­ют­ся ме­та­сим­во­ла­ми, и хо­тя в них есть нечто об­щее с тем, к че­му вы при­вык­ли в Bash, имеются и раз­ли­чия. На­при­мер, ? и * ис­поль­зу­ют­ся ина­че, и су­ще­ст­ву­ет до­воль­но длин­ный спи­сок ме­та­сим­во­лов, ис­поль­зуе­мых для по­строения мо­дуль­ной функ­ции по­ис­ка. Но идея все та же – нуд­ный руч­ной под­ход за­ме­ня­ет­ся ав­то­ма­ти­че­­ским. Изу­чение этих сим­во­лов и их ис­поль­зо­вания – ключ к ра­бо­те с ре­гу­ляр­ны­ми вы­ра­жения­ми, и команд­ная стро­ка – как всегда, луч­шее ме­сто для стар­та.

Perl при­шел в жизнь как язык для генера­ции от­че­тов, вслед­ст­вие че­го под­дер­жи­ва­ет ре­гу­ляр­ные вы­ра­жения так, как ника­кой дру­гой. Пусть вы не ха­кер Perl – в команд­ной стро­ке есть мно­го Perl-по­доб­но­го. Пре­крас­ный об­раз­чик – от­лич­ная ко­ман­да rename: это один из наи­бо­лее ши­ро­ко ис­поль­зуе­мых скрип­тов на Perl и по­то­му принима­ет ре­гу­ляр­ные вы­ра­жения без до­ба­воч­ных пре­об­ра­зо­ваний. Вот хо­ро­ший при­мер:

rename ‘s / htm$ / html / ’ *.htm
# Пе­ре­име­но­вать все фай­лы с рас­ши­ре­ни­ем ‘.htm’, обыч­ные для Windows, в бо­лее упот­ре­би­тель­ные ‘.html’.

Стро­ка, сле­дую­щая за ко­ман­дой rename, долж­на быть за­клю­че­на в оди­ноч­ные ка­выч­ки; пер­вая s в стро­ке оз­на­ча­ет за­ме­ну [substitution] – то, в чем Perl осо­бен­но хо­рош (воз­мож­ны, конеч­но, и дру­гие дей­ст­вия). Ка­ж­дый ар­гу­мент за­ме­ны от­де­ля­ет­ся пря­мым слэ­шем, и за­ме­на вы­пол­ня­ет­ся в со­от­вет­ст­вии с дву­мя при­ве­ден­ны­ми ре­гу­ляр­ны­ми вы­ра­жения­ми. Пер­вое вы­ра­жение оп­ре­де­ля­ет часть имени фай­ла, ко­то­рая бу­дет из­менена, а вто­рая – фай­лы, у ко­то­рых бу­дут из­менены име­на. Знак дол­ла­ра со­от­вет­ст­ву­ет сим­во­лам в кон­це вход­ной стро­ки, ко­то­рая в дан­ном слу­чае яв­ля­ет­ся рас­ши­рением фай­ла, а звез­доч­ка со­от­вет­ст­ву­ет всем вход­ным фай­лам, ана­ло­гич­но вы­бо­ру фай­лов по мас­ке в команд­ной стро­ке.

Впро­чем, за­ме­нять мож­но не толь­ко ви­ди­мые сим­во­лы, но и те, что не вид­ны, на­при­мер, про­бе­лы.

$ rename ‘s/ *//g’ *.ogg
# Уда­лить все про­бе­лы в фай­лах с му­зы­кой, взя­тые из имен до­ро­жек CD.

Это вы­ра­жение по­хо­же на при­мер с ‘html’. Про­из­во­дит­ся по­иск про­бе­ла, за ко­то­рым сле­ду­ет звез­доч­ка, оз­на­чаю­щая «все, что угод­но», и все най­ден­ные про­бе­лы за­ме­ня­ют­ся на «ничто» (т. е. уда­ля­ют­ся), по­это­му мы ви­дим два пря­мых слэ­ша под­ряд. За­вер­шаю­щая g в ре­гу­ляр­ном вы­ра­жении – обо­зна­чение гло­баль­ной за­ме­ны из Perl – га­ран­ти­ру­ет, что за­ме­на бу­дет про­из­ве­де­на во всех вход­ных фай­лах, а не толь­ко в пер­вом из обнаруженных.

Вто­рая по­пу­ляр­ная (да­же слиш­ком) ко­ман­да – tr. Она пре­об­ра­зу­ет од­ну стро­ку в дру­гую по­доб­но ко­ман­де rename, но ра­бо­та­ет не с фай­ла­ми, а со стан­дарт­ным вво­дом. Она немно­го на­по­ми­на­ет «sed для бед­ных», и вы ее освои­те, ес­ли когда-ли­бо за­гля­ды­ва­ли в справ­ку по sed. Стан­дарт­ный ввод tr – по­ток дан­ных, пе­ре­да­вае­мый ко­ман­де че­рез ка­нал Bash |, ко­то­рый су­ще­ст­вен­но от­ли­ча­ет­ся от ка­на­ла, ис­поль­зуе­мо­го ре­гу­ляр­ны­ми вы­ра­жения­ми. В ко­ман­де tr ин­те­рес­но то, что она вво­дит в ре­гу­ляр­ные вы­ра­жения идею спи­сков. Спи­сок оп­ре­де­ля­ет­ся в квад­рат­ных скоб­ках – и это удоб­ный спо­соб пе­ре­чис­лить кон­крет­ные зна­чения или ука­зать диа­па­зон свя­зан­ных. Ко­ман­да tr пре­об­ра­зу­ет зна­чения вход­но­го спи­ска в зна­чения, опи­сан­ные вы­ход­ным спи­ском:

cat file.txt | tr ‘[(abc|dog)]’ ‘[efg]’ > file_tr.txt
# Най­ти и за­ме­нить стро­ку ‘abc’ внут­ри тек­сто­во­го фай­ла стро­кой ‘efg’, и по­мес­тить их в но­вый файл с име­нем ‘file_tr.txt’

Есть мас­са спо­со­бов при­менения этой ко­ман­ды, но при­ве­ден­ный вы­ше при­мер – наи­бо­лее об­щий. Он ис­поль­зу­ет стан­дарт­ный ввод вме­сто прие­ма фай­ла в ка­че­­ст­ве ар­гу­мен­та, и мы пе­ре­на­прав­ля­ем вы­вод file.txt ко­ман­дой cat. Сле­дую­щая часть – наш пер­вый на­стоя­щий при­мер по­строения ре­гу­ляр­но­го вы­ра­жения; по­доб­ные ему встре­ча­ет­ся чуть ли не во всех ре­гу­ляр­ных вы­ра­жениях. Мы ис­поль­зу­ем два спи­ска, что по­ка­зы­ва­ют квад­рат­ные скоб­ки, для оп­ре­де­ления стро­ки вво­да и стро­ки, ко­то­рая за­менит ка­ж­дое вхо­ж­дение, а за­тем вы­вод бу­дет пе­ре­хва­чен и на­прав­лен в file_tr.txt.

Ус­лож­ним за­да­чу

По­лю­бо­пыт­ст­ву­ем фраг­мен­та­ми ре­гу­ляр­но­го вы­ра­жения в скоб­ках – за­ме­ны abc на efg, так как эти спи­ски не обя­за­ны со­сто­ять из букв. На­при­мер, [a-z] оз­на­ча­ет все бу­к­вы ме­ж­ду a и z. Ес­те­ст­вен­но, то же са­мое спра­вед­ли­во для цифр: про­сто за­мените сим­во­лы в скоб­ках. Хо­тя луч­шее до­ка­за­тель­ст­во мо­щи та­ких вы­ра­жений – ре­гу­ляр­ное вы­ра­жение, вы­пол­няю­щее по­иск ше­ст­на­дца­те­рич­но­го сим­во­ла. Это­го лег­ко достичь кон­ст­рук­ци­ей [0‑9a-fA-F], ко­то­рая до­пуска­ет бу­к­вы от A до F и все циф­ры.

Дру­гая воз­мож­ность ре­гу­ляр­ных вы­ра­жений, ис­поль­зуе­мых tr – управ­ляю­щие сим­во­лы. Эти сим­во­лы вид­ны толь­ко по ре­зуль­та­ту сво­его дей­ст­вия – на­при­мер, воз­врат ка­рет­ки или та­бу­ля­ция; и внут­ри ре­гу­ляр­но­го вы­ра­жения они пред­став­ля­ют­ся в ви­де об­рат­но­го слэ­ша, за ко­то­рым сле­ду­ет дру­гой сим­вол. На­при­мер, та­бу­ля­ция – это \v, сим­вол пе­ре­хо­да на но­вую стро­ку – \n, и есть мас­са дру­гих. С по­мо­щью этих сим­во­лов в вы­ра­жениях для по­ис­ка и за­ме­ны мож­но от­фор­ма­ти­ро­вать ваш текст.

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

grep ‘\(dog\|cat\)s’ pets.txt
# По­иск со­бак ‘dogs’ или ко­шек ‘cats’ в тек­сто­вом фай­ле.

Дру­гая удоб­ная воз­мож­ность для по­ис­ка тек­ста – опе­ра­тор усло­вия |. С его по­мо­щью мож­но за­дать несколь­ко аль­тер­на­тив для со­от­вет­ст­вия в ре­гу­ляр­ном вы­ра­жении. Им мож­но восполь­зо­вать­ся, на­при­мер, когда нуж­но учесть раз­но­тык в на­пи­сании имен или когда есть спи­сок аль­тер­на­тив. До­ба­вить оп­цию or нетруд­но: нуж­но про­сто раз­де­лить ею все стро­ки и до­пи­сать ко всем стро­кам, кро­ме по­следней, сим­вол \. Он ну­жен для рас­по­зна­вания сим­во­ла |, а так­же необ­хо­дим в на­ча­ле спи­ска в скоб­ках: имен­но по нему пар­сер уз­на­ет, что в скоб­ках на­хо­дит­ся спи­сок оп­ций. Все, что идет сра­зу по­сле ско­бок, пе­ре­ме­ща­ет­ся в конец стро­ки по­ис­ка, и мы поль­зо­ва­лись этой воз­мож­но­стью в при­ме­ре вы­ше, что­бы до­ба­вить бу­к­ву s к кон­цу dog или cat, для уче­та форм мно­же­ст­вен­но­го чис­ла.

grep 192\.168\.1\.* addresses.txt
# По­иск в тек­сто­вом фай­ле ука­зан­но­го диа­па­зо­на IP-ад­ре­сов.

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

grep ‘^.*example[^.]*line.*\.’ test.txt 1
# По­иск слов ‘example’ и ‘line’ внут­ри од­но­го пред­ло­же­ния.

Для уп­раж­не­ний с ре­гу­ляр­ны­ми вы­ра­же­ния­ми да­же не нуж­на ко­манд­ная стро­ка — мож­но обой­тись OpenOffice.org.

Понимание ре­гек­спов

При­ве­ден­ный вы­ше при­мер – хо­ро­шая ил­лю­ст­ра­ция то­го, как, при­ло­жив со­всем немно­го уси­лий, мы поч­ти на­прочь со­рва­ли по­кров та­ин­ст­вен­но­сти с ре­гу­ляр­ных вы­ра­жений – мы уже рас­смот­ре­ли все их ком­понен­ты. Ка­рат в на­ча­ле стро­ки по­ис­ка ищет на­ча­ло но­вой стро­ки или аб­за­ца, от­де­лен­но­го воз­вра­том ка­рет­ки. Сле­дую­щие за ним .* со­от­вет­ст­ву­ют лю­бо­му ко­ли­че­­ст­ву сим­во­лов по­сле этой точ­ки, по­ка не бу­дет най­ден example. Да­лее идет хит­рый ку­со­чек – [^.] оз­на­ча­ет, что по­иск бу­дет счи­тать­ся успеш­ным, толь­ко ес­ли ме­ж­ду сло­ва­ми example и line нет точ­ки, то есть оба сло­ва на­хо­дят­ся в од­ном пред­ло­жении. На­конец, сим­во­лы .*\. в кон­це стро­ки по­ис­ка ищут весь осталь­ной текст, пре­ж­де чем сно­ва ис­кать точ­ку в кон­це то­го же пред­ло­жения. В конеч­ном ре­зуль­та­те мы по­лу­ча­ем гиб­кий по­ис­ко­вый ал­го­ритм, ко­то­рый мож­но мо­ди­фи­ци­ро­вать для раз­лич­ных ти­пов по­ис­ко­вых за­дач, а так как он ис­поль­зу­ет grep, мож­но восполь­зо­вать­ся неко­то­ры­ми его функ­ция­ми, что­бы уп­ро­стить вы­ра­жение. На­при­мер, мож­но до­ба­вить ключ -i, что­бы вы­ра­жение бы­ло нечув­ст­ви­тель­ным к ре­ги­ст­ру, или ключ -c, что­бы под­счи­тать ко­ли­че­­ст­во со­от­вет­ст­вий.

sed ‘s / dog /  / g’ pets.txt
# ‘sed’ ска­ни­ру­ет тек­сто­вый файл и уда­ля­ет все вхо­ж­де­ния сло­ва‘dog’.

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

В при­ве­ден­ном вы­ше при­ме­ре пер­вая s ак­ти­ви­зи­ру­ет ре­жим за­ме­ны sed. Это ме­ня­ет по­ве­дение «до сле­дую­ще­го /» на «до вто­ро­го /». К то­му же в этом при­ме­ре нет стро­ки за­ме­ны. Два пря­мых слэ­ша вме­сто нее оз­на­ча­ют, что пер­вое сло­во бу­дет за­менено «ничем» ме­ж­ду слэ­ша­ми, то есть, по су­ти, уда­ле­но. Что­бы из­менения не за­тро­ну­ли ис­ход­ный файл, sed на­прав­ля­ет свой вы­вод в тер­ми­нал – вы бы­ст­ро уви­ди­те, все ли ра­бо­та­ет. Ес­ли вы хо­ти­те со­хранить вы­вод в дру­гом фай­ле, про­сто до­бавь­те >newfile.txt.

sed ‘s / <[^>]*> /  / g’ index.html
# Уб­рать все HTML-тэ­ги на web-стра­ни­це, ос­та­вив толь­ко текст

Ре­жим за­ме­ны мо­жет быть ис­поль­зо­ван для ре­шения мно­же­ст­ва за­дач, вклю­чая мно­гие из ре­шае­мых grep. На­при­мер, что­бы уда­лить HTML-тэ­ги из фай­ла web-страницы, мож­но со­единить сим­во­лы для по­ис­ка на­ча­ла тэ­га, вы­брать текст ме­ж­ду сим­во­ла­ми от­кры­тия и за­кры­тия тэ­га и уда­лить их точ­но так же, как в пре­ды­ду­щем при­ме­ре. Слож­ный фраг­мент ко­да в се­ре­дине вы­де­ля­ет текст внут­ри ско­бок и ис­поль­зу­ет его в ка­че­­ст­ве за­ме­ны.

Те­перь мы зна­ко­мы с осно­ва­ми ре­гу­ляр­ных вы­ра­жений и c при­ме­ра­ми их при­менения. С по­мо­щью од­но­го из этих ме­то­дов вы смо­же­те рас­ши­рить не­ко­то­рые из на­ших идей и пре­вра­тить про­стые за­про­сы в бо­лее слож­ные. Ес­ли вы по­баи­вае­тесь ко­манд­ной стро­ки, не­об­хо­ди­мый функ­цио­нал мож­но най­ти в при­ло­же­ни­ях вро­де OpenOffice.org или Kodos.

Ак­те­ры и ро­ли

Вот крат­кое опи­сание зна­чений ка­ж­до­го из этих спе­ци­аль­ных сим­во­лов.

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

  • . (точ­ка) Оз­на­ча­ет один сим­вол в мас­ках фай­лов, как ?, но так­же вклю­ча­ет неви­ди­мые сим­во­лы вро­де про­бе­ла. Но не вклю­ча­ет сим­вол пе­ре­во­да стро­ки – это важ­но помнить, вы­пол­няя по­иск по ко­ду.
  • * (звез­доч­ка, звез­доч­ка Клини) Ана­ло­гич­но зна­чению в ин­те­рак­тив­ной обо­лоч­ке, звез­доч­ка за­ме­ня­ет ноль или бо­лее сим­во­лов, пред­ше­ст­вую­щих вы­ра­жению: так, a*z со­от­вет­ст­ву­ет всем сло­вам, на­чи­наю­щим­ся с ‘a’ и за­кан­чи­ваю­щи­ми­ся на ‘z’, но так­же и тем, что про­сто за­кан­чи­ва­ют­ся на ‘z’.
  • ^ (ка­рат, клин, шля­па, до­мик) Это один из са­мых рас­про­странен­ных сим­во­лов в ре­гу­ляр­ных вы­ра­жениях, и он оз­на­ча­ет про­сто на­ча­ло вход­ной стро­ки – на­при­мер, пер­вую бу­к­ву имени фай­ла.
  • $ (пе­со, дол­лар) Име­ет про­ти­во­по­лож­ное ка­ра­ту зна­чение и со­от­вет­ст­ву­ет сим­во­лам в кон­це вход­ной стро­ки, на­при­мер, рас­ши­рению фай­ла.
  • () (со­дер­жи­мое внут­ри ско­бок) Со­дер­жат од­но вы­ра­жение, так что оно мо­жет ис­поль­зо­вать­ся вме­сте с дру­ги­ми фраг­мен­та­ми ко­да.
  • | (вер­тикаль­ная чер­та, ка­нал) Как и в неко­то­рых язы­ках про­грам­ми­ро­вания, вер­тикаль­ная чер­та – ло­ги­че­­ское ИЛИ, ис­поль­зуе­мое в тех слу­ча­ях, когда нуж­но про­из­ве­сти по­иск по несколь­ким вы­ра­жениям, за­клю­чен­ным в скоб­ки.
  • [] (со­дер­жи­мое внут­ри квад­рат­ных ско­бок) Квад­рат­ные скоб­ки обыч­но со­дер­жат спи­сок сим­во­лов, для ко­то­рых нуж­но за­дать од­но вхо­ж­дение. Это осо­бен­но удоб­но, когда нуж­но ис­кать по на­бо­ру сим­во­лов, у ко­то­рых нет ниче­го об­ще­го.
  • [^] До­бав­ление сим­во­ла ка­ра­та в на­ча­ле спи­ска в квад­рат­ных скоб­ках ме­ня­ет его дей­ст­вие на про­ти­во­по­лож­ное: те­перь его зна­чение со­от­вет­ст­ву­ет сим­во­лу, не со­дер­жа­ще­му­ся в скоб­ках.

По­строение ре­гу­ляр­ных вы­ра­жений че­рез GUI

Один из луч­ших спо­со­бов изу­чить ра­бо­ту ре­гу­ляр­ных вы­ра­же­ний — взять ви­зу­аль­ный ре­дак­тор вро­де Kodos и по­уп­раж­нять­ся с па­роч­кой го­то­вых вы­ра­же­ний.

Ре­гу­ляр­ные вы­ра­жения бы­ва­ют на­столь­ко слож­ны, что кры­шу сно­сит. И да­же ес­ли вы умее­те их пи­сать, соз­дание вы­ра­жения по­сложнее, ра­бо­таю­ще­го долж­ным об­ра­зом – обыч­но путь проб и оши­бок. В обо­их слу­ча­ях по­мо­жет ви­зу­аль­ная сре­да по­строения ре­гу­ляр­ных вы­ра­жений. Она мо­жет вы­сту­пать как ин­тег­ри­ро­ван­ная сре­да раз­ра­бот­чи­ка для по­строения вы­ра­жений, ото­бра­жать ре­зуль­та­ты в ре­аль­ном вре­мени с до­бав­лением и уда­лением ком­понен­тов и под­све­чи­вать все ошиб­ки в вы­ра­жении по ме­ре их по­яв­ления.

В KDE 3 бы­ла пре­крас­ная ути­лит­ка, ко­то­рая ис­поль­зо­ва­лась как вид­жет в при­ло­жениях вро­де KMail и как са­мо­стоя­тель­ное при­ло­жение. К со­жа­лению, KRegExEditor не пе­ре­жил пе­ре­хо­да на KDE 4. Луч­шая аль­тер­на­ти­ва, ко­то­рую мы смог­ли най­ти – Kodos. Это ути­ли­та для ре­гу­ляр­ных вы­ра­жений в Python, но она пре­крас­но по­дой­дет для по­строения лю­бых дру­гих ре­гу­ляр­ных вы­ра­жений. Вы вво­ди­те вы­ра­жение в верхнее по­ле и фраг­мент ис­ко­мой стро­ки в нижнее, и на вклад­ках в нижнем окне поя­вит­ся ин­фор­ма­ция об ин­тер­пре­та­ции и то­го, и дру­го­го. На­при­мер, мож­но вве­сти вы­ра­жение для про­вер­ки ад­ре­са элек­трон­ной поч­ты в верхнее по­ле и сам ад­рес в по­ле по­ис­ка, и ес­ли вы­ра­жение ра­бо­та­ет пра­виль­но, вы уви­ди­те ад­рес в по­ле со­от­вет­ст­вия.

Личные инструменты
  • Купить электронную версию
  • Подписаться на бумажную версию