Примери за регулярен израз на Egrep. Използване на Grep и регулярни изрази за намиране на текстови модели в Linux

Относно този урок

Добре дошли в Основи на администрацията, вторият от четирите урока, предназначени да ви подготвят за изпит 101 в Linux Professional Institute. В тази част ще разгледаме как да използваме регулярни изрази за търсене на текст във файлове въз основа на шаблони. След това ще се запознаете със „Стандарта на йерархията файлова система” (Filesystem Hierarchy Standard или накратко FHS), ние също ще ви покажем как да намерите файловете, от които се нуждаете във вашата система. След това ще научите как да поемете пълен контрол върху процесите в Linux, като ги стартирате заден план, разглеждане на списъка с процеси, отделянето им от терминала и много други. Това, което следва, е кратко въведение в конвейерите, пренасочванията и командите за обработка на текст. Накрая ще ви запознаем с модулите на ядрото на Linux.

По-специално, тази част от урока (Част 2) е идеална за тези, които вече имат добри основни познания по bash и искат добро въведение в основните административни задачи на Linux. Ако сте нов в Linux, препоръчваме ви първо да завършите първата част от тази поредица с инструкции. За някои повечето от тези материали ще бъдат нови, но по-опитните потребители на Linux може да го намерят за чудесен начин да обобщят основните си административни умения.



Ако сте изучавали първия брой на този урок за цел, различна от обучение за изпита LPI, тогава може да не е необходимо да препрочитате този брой. Въпреки това, ако планирате да се явите на изпита, силно ви препоръчваме да прочетете отново тази преработена версия на урока.

Регулярни изрази

Какво е "регулярен израз"?

Регулярният израз (според англ. regular expression, съкр. "regexp" или "regex", в родината понякога се нарича "regular" - прибл. Лейн) е специален синтаксис, използван за описание на текстови модели. В Linux системите регулярните изрази се използват широко за съвпадение на шаблони в текст и за операции за търсене и замяна на текстови потоци.

В сравнение с глобирането

След като започнем да разглеждаме регулярните изрази, може да забележите, че синтаксисът им е много подобен на синтаксиса за глобиране на името на файла, който разгледахме в част 1. Въпреки това, не се заблуждавайте, това сходство е много повърхностно. Регулярните изрази и шаблоните за глобиране, дори когато изглеждат подобни, са коренно различни неща.

прост подниз

Без това предупреждение, нека да разгледаме най-основното нещо за регулярните изрази, най-простия подниз. За да направим това, ще използваме "grep", команда, която сканира съдържанието на файл според даден регулярен израз. grep отпечатва всеки ред, който съответства на регулярния израз, като игнорира останалите:

$ grep bash /etc/passwd
оператор:x:11:0:оператор:/root:/bin/bash root:x:0:0::/root:/bin/bash ftp:x:40:1::/home/ftp:/bin/ баш

По-горе, първият параметър за grep е regex; второто е името на файла. grep прочете всеки ред от /etc/passwdи приложи обикновен подниз с регулярен израз "bash" към него, търсейки съвпадение. Ако се намери съвпадение, тогава grep отпечатва целия ред; в противен случай линията беше игнорирана.

Разбиране на прост подниз

Като цяло, ако търсите подниз, можете просто да го посочите буквално, без да използвате никакви "специални" знаци. Трябва да внимавате само ако вашият подниз съдържа +, ., *, [, ] или \, в който случай тези знаци трябва да бъдат екранирани с обратна наклонена черта и поднизът да бъде ограден в кавички. Ето няколко примера за регулярни изрази като обикновен подниз:

  • /tmp (търсете /tmp ред)
  • "\" (търсене в низ)
  • "\*смешно\*" (търсене на низ *смешно*)
  • "ld\.so" (търсене на низ ld.so)

Метазнаци

С регулярни изрази, използващи метасимволи, е възможно да се извършват много по-сложни търсения, отколкото в примерите, които наскоро бяха разгледани. Един такъв метазнак е "." (точка), което съответства на всеки отделен знак:

$ grep dev.sda /etc/fstab
/dev/sda3 / reiserfs noatime,ro 1 1 /dev/sda1 /boot reiserfs noauto,noatime,notail 1 2 /dev/sda2 swap swap sw 0 0 #/dev/sda4 /mnt/extra reiserfs noatime,rw 1 1

В този пример текстът dev.sda не се появява буквално на нито един от редовете в /etc/fstab. Grep обаче не го сканира буквално за линията dev.sda, а за модела dev.sda. Не забравяйте, че "." ще съответства на всеки отделен знак. Както можете да видите, "." е функционално еквивалентен на това как работи метасимволът "?". в glob замествания.

Използване

Ако искаме да посочим знак по-конкретно от ".", можем да използваме [ и ] (квадратни скоби), за да посочим поднабор от знаци, които да съответстват:

$ grep dev.sda /etc/fstab
/dev/sda1 /boot reiserfs noauto,noatime,notail 1 2 /dev/sda2 swap swap sw 0 0

Както можете да видите, по-специално, тази синтактична конструкция работи идентично с конструкцията "" в glob заместване на име на файл. Отново, това е една от неяснотите при изучаването на регулярни изрази: синтаксисът е подобен, но не идентичен, на глобалните замествания, което е объркващо.

Използване на [^]

Можете да обърнете значението на квадратните скоби, като поставите ^ точно след [. В този случай скобите ще съответстват на всеки знак, който НЕ е посочен в тях. Отново забележете, че използваме [^] с regex и [!] с glob:

$ grep dev.hda[^12] /etc/fstab
/dev/hda3 / reiserfs noatime,ro 1 1 #/dev/hda4 /mnt/extra reiserfs noatime,rw 1 1

Различен синтаксис

Много е важно да се отбележи, че синтаксисът в квадратните скоби е фундаментално различен от останалата част от регулярния израз. Например, ако поставите "." вътре в квадратните скоби, това ще позволи на квадратните скоби да съвпадат с "." буквално, точно като 1 и 2 в примера по-горе. За сравнение, "." поставени извън квадратни скоби ще се интерпретират като метасимвол, освен ако "\" не е с префикс. Можем да се възползваме от този факт, за да отпечатаме редове от /etc/fstab, които съдържат реда dev.sda, както е написано:

$ grep dev[.]sda /etc/fstab

Освен това можем да напишем:

$ grep "dev\.sda" /etc/fstab

Тези регулярни изрази вероятно не съвпадат с нито един от вашите редове. /etc/fstabфайл.

Математически символ *

Някои метасимволи сами по себе си не отговарят на нищо, но променят значението на предишния знак. Един такъв знак е * (звездичка), който се използва за съвпадение на нула или повече срещания на предходния знак. Имайте предвид, че това означава, че * има различно значение в регулярните изрази, отколкото в глобирането. Ето няколко примера и обърнете специално внимание на случаите, когато съпоставянето на регулярни изрази се различава от заместванията на glob:

  • ab*cсъвпада с "abbbbc", но не и с "abqc" (в случай на заместване на glob и двата низа ще съответстват на модела. Разбирате ли защо?)
  • ab*cсъвпада с "abc", но не и с "abbqbbc" (отново, при заместване на glob моделът съвпада и с двата низа)
  • ab*cсъвпада с "ac", но не и с "cba" (в случай на глобиране, нито "ac", нито "cba" съвпадат с шаблона)
  • бъдасъвпада с "bqe" и "be" (глобалното заместване съвпада с "bqe", но не и с "be")
  • бъдасъвпада с "bccqqe", но не и с "bccc" (при глобиране моделът също ще съвпада с първия, но не и с втория)
  • бъдасъвпада с "bqqcce", но не и с "cqe" (същото със заместването на glob)
  • бъдаудовлетворява "bbbeee" (но не и в случай на глобиране)
  • .* съвпада с който и да е низ (глобалното заместване съвпада само с низове, започващи с ".")
  • фу.*ще съответства на всеки подниз, започващ с "foo" (в случай на заместване на глоба, този модел ще съответства на низове, започващи с четирите знака "foo.")

И така, за да обобщим, низът "ac" съвпада с регулярния израз "ab*c", тъй като звездичката също позволява предходният израз (b) да бъде повторен нула пъти. И отново, струва си да отбележите за себе си, че метасимволът * в регулярните изрази се интерпретира напълно различно от знака * в глобалните замествания.

Начало и край на ред

Последните метасимволи, които ще разгледаме подробно, са ^ и $, които се използват съответно за съпоставяне на началото и края на низ. Като използвате ^ в началото на вашия регулярен израз, вие "прикрепяте" вашия шаблон към началото на реда. В следващия пример използваме регулярния израз ^#, който съответства на всеки низ, който започва със знак #:

$ grep ^# /etc/fstab

#

Регулярни изрази на пълен ред

^ и $ могат да се комбинират, за да съответстват на целия низ. Например, следният регулярен израз ще съответства на низове, започващи с # и завършващи с ".", с произволен брой знаци между тях:

$ grep "^#.*\.$" /etc/fstab
# /etc/fstab: информация за статична файлова система.

В примера по-горе затворихме нашия регулярен израз в единични кавички, за да предотвратим интерпретирането на символа $ от обвивката. Без единичните кавички, $ щеше да изчезне от нашия регулярен израз, преди grep дори да го види.

За авторите

Даниел Робинс

Даниел Робинс – основател и създател на общността Gentoo операционна система Gentoo Linux. Даниел живее в Ню Мексико със съпругата си Мери и две енергични дъщери. Той също така е основател и ръководител на Funtoo и е написал много технически статии за IBM developerWorks, Intel Developer Services и C/C++ Users Journal.

Крис Хаузър

Крис Хаузър е защитник на UNIX от 1994 г., когато се присъединява към административния екип в университета Тейлър, Индиана, САЩ, където получава бакалавърска степен по компютърни науки и математика. Оттогава той работи в различни области, включително уеб приложения, редактиране на видео, UNIX драйвери и криптографска сигурност. В момента работи в Sentry Data Systems. Крис също е допринесъл за много проекти с отворен код като Gentoo Linux и Clojure и е съавтор на The Joy of Clojure.

Арон Грифис

Ейрън Грифис живее в района на Бостън, където е прекарал последното десетилетие, работейки за Hewlett-Packard по проекти като UNIX мрежови драйвери за Tru64, сертифициране за сигурност на Linux, Xen и KVM виртуализация и най-скоро платформата HP ePrint. В свободното си време от програмиране Арън предпочита да размишлява върху проблемите на програмирането, докато кара колело, жонглира с бухалки или аплодира за професионалния бейзболен отбор Бостън Ред Сокс.

За да обработвате напълно текстове в bash скриптове със sed и awk, просто трябва да разбирате регулярните изрази. Реализации на това най-полезният инструментмогат да бъдат намерени буквално навсякъде и въпреки че всички регулярни изрази са подредени по подобен начин, базирани на едни и същи идеи, работата с тях има определени характеристики в различни среди. Тук ще говорим за регулярни изрази, които са подходящи за използване в скриптове на командния ред на Linux.

Този материал е предназначен като въведение в регулярните изрази за тези, които може да не знаят какво представляват регулярните изрази. Затова нека започнем от самото начало.

Какво представляват регулярните изрази

За мнозина, когато за първи път видят регулярни изрази, веднага възниква мисълта, че имат безсмислена бъркотия от знаци пред тях. Но това, разбира се, далеч не е така. Погледнете например този регулярен израз


Според нас дори абсолютно начинаещ веднага ще разбере как работи и защо е необходим :) Ако не разбирате съвсем, просто прочетете и всичко ще си дойде на мястото.
Регулярният израз е модел, който програми като sed или awk използват за филтриране на текст. Шаблоните използват обикновени ASCII знаци, които представляват себе си, и така наречените метасимволи, които играят специална роля, например, позволявайки ви да се позовавате на определени групи знаци.

Типове регулярни изрази

Реализациите на регулярни изрази в различни среди, например в езици за програмиране като Java, Perl и Python, в инструменти на Linux като sed, awk и grep, имат някои особености. Тези функции зависят от така наречените машини за обработка на регулярни изрази, които се занимават с интерпретацията на шаблони.
Linux има две машини за регулярен израз:
  • Машина, която поддържа стандарта POSIX Basic Regular Expression (BRE).
  • Машина, която поддържа стандарта POSIX Extended Regular Expression (ERE).
Повечето помощни програми на Linux отговарят поне на стандарта POSIX BRE, но някои помощни програми (включително sed) разбират само подмножество от стандарта BRE. Една от причините за това ограничение е желанието да се направят такива помощни програми възможно най-бързи в текстообработката.

Стандартът POSIX ERE често се прилага в езици за програмиране. Позволява ви да използвате много инструменти, когато разработвате регулярни изрази. Например, това могат да бъдат специални последователности от знаци за често използвани шаблони, като търсене на отделни думи или набори от числа в текста. Awk поддържа стандарта ERE.

Има много начини за разработване на регулярни изрази, в зависимост от мнението на програмиста и от характеристиките на двигателя, под който са създадени. Не е лесно да се напишат общи регулярни изрази, които всеки двигател може да разбере. Затова ще се съсредоточим върху най-често използваните регулярни изрази и ще разгледаме спецификата на тяхната реализация за sed и awk.

POSIX BRE регулярни изрази

Може би най-простият BRE шаблон е регулярен израз за намиране на точно съвпадение на последователност от знаци в текста. Ето как изглежда търсенето на низ в sed и awk:

$ echo "Това е тест" | sed -n "/test/p" $ echo "Това е тест" | awk "/test/(print $0)"

Намиране на текст по модел в sed


Намиране на текст по модел в awk

Може да забележите, че търсенето на даден модел се извършва, без да се взема предвид точното местоположение на текста в низа. Освен това броят на срещанията няма значение. След като регулярният израз намери дадения текст навсякъде в низа, низът се счита за подходящ и се предава за по-нататъшна обработка.

Когато работите с регулярни изрази, имайте предвид, че те са чувствителни към главни и малки букви:

$ echo "Това е тест" | awk "/Test/(print $0)" $ echo "Това е тест" | awk "/test/(print $0)"

Регулярните изрази са чувствителни към главни и малки букви

Първият регулярен израз не намери съвпадения, тъй като думата "тест", която започва с главна буква, не се среща в текста. Вторият, конфигуриран да търси дума, написана с главни букви, намери подходящ низ в потока.

В регулярните изрази можете да използвате не само букви, но и интервали и цифри:

$ echo "Това отново е тест 2" | awk "/тест 2/(печат $0)"

Намиране на част от текст, съдържащ интервали и числа

Интервалите се третират от механизма за регулярен израз като обикновени знаци.

Специални символи

Когато използвате различни знаци в регулярни изрази, трябва да имате предвид няколко неща. Например, има някои специални символи или метасимволи, които изискват специален подход, когато се използват в шаблон. Ето ги и тях:

.*^${}\+?|()
Ако един от тях е необходим в шаблона, той ще трябва да бъде екраниран с обратна наклонена черта (обратна наклонена черта) - \ .

Например, ако трябва да намерите знак за долар в текста, той трябва да бъде включен в шаблона, предшестван от екраниращ знак. Да кажем, че има файл myfile със следния текст:

В джоба ми има 10$
Знакът за долар може да бъде открит с модел като този:

$ awk "/\$/(печат $0)" myfile

Използване на специален знак в шаблон

Освен това обратната наклонена черта също е специален знак, така че ако искате да я използвате в шаблон, трябва също да я екранирате. Изглежда като две наклонени черти, следващи една след друга:

$ echo "\ е специален знак" | awk "/\\/(печат $0)"

Екраниране на обратно наклонена черта

Въпреки че наклонената черта не е в горния списък със специални знаци, опитът да се използва в регулярен израз, написан за sed или awk, ще доведе до грешка:

$ echo "3 / 2" | awk "///(печат $0)"

Неправилно използване на наклонена черта в шаблон

Ако е необходимо, то също трябва да бъде екранирано:

$ echo "3 / 2" | awk "/\//(печат $0)"

Бягство от наклонена черта

Символи за котва

Има два специални знака за закрепване на шаблон към началото или края на текстов низ. Символът за капачка - ^ ви позволява да опишете последователности от знаци, които са в началото на текстовите редове. Ако моделът, който търсите, се появи на друго място в низа, регулярният израз няма да отговори на него. Използването на този символ изглежда така:

$ echo "добре дошли в уебсайта likegeeks" | awk "/^likegeeks/(print $0)" $ echo "likegeeks website" | awk "/^likegeeks/(печат $0)"

Търсене на модел в началото на низ

Символът ^ е предназначен за търсене на модел в началото на реда, като се взема предвид и регистърът на буквите. Нека видим как това ще се отрази на обработката на текстов файл:

$ awk "/^this/(print $0)" myfile


Търсене на модел в началото на ред в текст от файл

Когато използвате sed, ако поставите край където и да е в шаблон, той ще бъде третиран като всеки друг нормален символ:

$ echo "Това ^ е тест" | sed -n "/s ^/p"

Капачката не е в началото на модела в sed

В awk, когато се използва същия шаблон, даденият символ трябва да бъде екраниран:

$ echo "Това ^ е тест" | awk "/s \^/(печат $0)"

Капак не е в началото на шаблон в awk

С търсенето на текстови фрагменти в началото на реда го разбрахме. Ами ако трябва да намерите нещо в края на ред?

Знакът за долар - $ , който е знакът за котва за края на реда, ще ни помогне за това:

$ echo "Това е тест" | awk "/test$/(print $0)"

Намиране на текст в края на ред

И двата знака за котва могат да се използват в един и същи модел. Нека обработим файла myfile, чието съдържание е показано на фигурата по-долу, като използваме следния регулярен израз:

$ awk "/^това е тест$/(печат $0)" myfile


Шаблон, който използва специални знаци за началото и края на низ

Както можете да видите, шаблонът реагира само на низ, който напълно съответства на дадената последователност от символи и тяхното местоположение.

Ето как да филтрирате празните редове с помощта на опорни знаци:

$ awk "!/^$/(print $0)" myfile
В този шаблон използвах символа за отрицание, удивителния знак - ! . Използването на този шаблон търси редове, които не съдържат нищо между началото и края на реда, и благодарение на удивителния знак се отпечатват само редове, които не отговарят на този шаблон.

Символ точка

Точката се използва за търсене на всеки отделен знак, с изключение на знака за нов ред. Нека предадем файла myfile на такъв регулярен израз, чието съдържание е дадено по-долу:

$ awk "/.st/(print $0)" myfile


Използване на точка в регулярни изрази

Както може да се види от изхода, само първите два реда от файла отговарят на шаблона, тъй като съдържат последователността от знаци "st", предшествана от друг знак, докато третият ред не съдържа подходяща последователност, а четвъртият ред прави, но е в самото начало на реда.

Класове на знаци

Точка съответства на всеки отделен знак, но какво ще стане, ако искате да ограничите набора от знаци, които търсите по-гъвкаво? В такава ситуация можете да използвате класове на знаци.

Благодарение на този подход можете да организирате търсене на всеки знак от даден набор. За описание на символен клас се използват квадратни скоби -:

$ awk "/th/(print $0)" myfile


Описание на символен клас в регулярен израз

Тук търсим поредица от символи "th", предшествани от знака "o" или знака "i".

Класовете са полезни, когато търсите думи, които могат да започват с главна или малка буква:

$ echo "това е тест" | awk "/his е тест/(print $0)" $ echo "Това е тест" | awk "/неговото е тест/(печат $0)"

Търсете думи, които могат да започват с малка или главна буква

Класовете символи не се ограничават до букви. Тук могат да се използват и други знаци. Невъзможно е да се каже предварително в каква ситуация ще са необходими класовете - всичко зависи от проблема, който се решава.

Отричане на класове герои

Класовете символи могат също да се използват за решаване на обратния проблем, описан по-горе. А именно, вместо да търсите символи, включени в класа, можете да организирате търсене на всичко, което не е включено в класа. За да постигнете това поведение на регулярен израз, трябва да поставите знак ^ пред списъка със знаци на класа. Изглежда така:

$ awk "/[^oi]th/(print $0)" myfile


Търсене на герои извън клас

В този случай ще бъдат намерени поредици от знаци "th", пред които няма нито "o", нито "i".

Диапазони на знаци

В класове знаци можете да опишете диапазони от знаци с помощта на тирета:

$ awk "/st/(print $0)" myfile


Описване на диапазон от знаци в клас знаци

В този пример регулярният израз съответства на последователността от знаци "st", предшествана от всеки знак, разположен по азбучен ред между знаците "e" и "p".

Диапазони могат да бъдат създадени и от числа:

$ echo "123" | awk "//" $ echo "12a" | awk "//"

Регулярен израз за намиране на произволни три числа

Един клас знаци може да съдържа множество диапазони:

$ awk "/st/(print $0)" myfile


Символен клас, състоящ се от множество диапазони

Този регулярен израз ще съответства на всички последователности "st", предшествани от знаци от диапазони a-fи м-з .

Класове със специални герои

BRE има специални символни класове, които могат да се използват при писане на регулярни изрази:
  • [[:alpha:]] - съвпада с всеки азбучен знак, написан с главни или малки букви.
  • [[:alnum:]] - съответства на всеки буквено-цифров знак, а именно знаци в диапазоните 0-9, A-Z, a-z.
  • [[:blank:]] - Съвпада с интервал и раздел.
  • [[:digit:]] - всеки цифров знак от 0 до 9 .
  • [[:upper:]] - главни букви - A-Z.
  • [[:lower:]] - малки букви - a-z.
  • [[:print:]] - съвпада с всеки знак за печат.
  • [[:punct:]] - отговаря на препинателните знаци.
  • [[:интервал:]] - празни знаци, по-специално - интервал, табулация, знаци NL, FF, VT, CR.
Можете да използвате специални класове в шаблони като този:

$ echo "abc" | awk "/[[:alpha:]]/(print $0)" $ echo "abc" | awk "/[[:digit:]]/(print $0)" $ echo "abc123" | awk "/[[:цифра:]]/(печат $0)"


Специални символни класове в регулярни изрази

Символ звездичка

Ако поставите звездичка след знак в шаблон, това ще означава, че регулярният израз ще работи, ако знакът се появи в низа произволен брой пъти - включително ситуацията, когато знакът липсва в низа.

$ echo "тест" | awk "/tes*t/(print $0)" $ echo "tessst" | awk "/tes*t/(печат $0)"


Използване на знака * в регулярни изрази

Този заместващ знак обикновено се използва за работа с думи, които постоянно са изписани неправилно, или за думи, които могат да бъдат изписани по различен начин:

$ echo "Харесвам зелен цвят" | awk "/colou*r/(print $0)" $ echo "Харесвам зелен цвят" | awk "/цвят*r/(печат $0)"

Намиране на дума, която има различен правопис

В този пример един и същ регулярен израз съвпада както с думата „цвят“, така и с думата „цвят“. Това се дължи на факта, че знакът "u", последван от звездичка, може или да отсъства, или да се появи няколко пъти подред.

Друга полезна функция, произтичаща от знака звездичка, е да го комбинирате с точка. Тази комбинация позволява на регулярния израз да отговаря на произволен брой знаци:

$ awk "/this.*test/(print $0)" myfile


Шаблон, който отговаря на произволен брой знаци

В този случай няма значение колко и какви знаци има между думите "това" и "тест".

Звездицата може да се използва и с класове символи:

$ echo "st" | awk "/s*t/(print $0)" $ echo "sat" | awk "/s*t/(print $0)" $ echo "set" | awk "/s*t/(печат $0)"


Използване на звездичката с класове знаци

И в трите примера регулярният израз работи, защото звездичката след класа на знаците означава, че ако бъдат намерени произволен брой символи "a" или "e" или ако не бъдат намерени, низът ще съответства на дадения шаблон.

POSIX ERE регулярни изрази

POSIX ERE шаблоните, които някои помощни програми на Linux поддържат, може да съдържат допълнителни знаци. Както вече споменахме, awk поддържа този стандарт, но sed не.

Тук ще разгледаме най-често използваните знаци в шаблоните на ERE, които ще ви бъдат полезни, когато създавате свои собствени регулярни изрази.

▍Въпросителен знак

Въпросителният знак показва, че предходният знак може да се появи веднъж или изобщо да не се появи в текста. Този символ е един от метасимволите за повторение. Ето няколко примера:

$ echo "tet" | awk "/tes?t/(print $0)" $ echo "test" | awk "/tes?t/(print $0)" $ echo "testst" | awk "/tes?t/(печат $0)"


Въпросителен знак в регулярни изрази

Както можете да видите, в третия случай буквата „s“ се среща два пъти, така че регулярният израз не отговаря на думата „testst“.

Въпросителният знак може да се използва и с класове символи:

$ echo "tst" | awk "/t?st/(print $0)" $ echo "test" | awk "/t?st/(print $0)" $ echo "tast" | awk "/t?st/(print $0)" $ echo "taest" | awk "/t?st/(print $0)" $ echo "teest" | awk "/t?st/(печат $0)"


Въпросителен знак и класове знаци

Ако в низа няма знаци от класа или един от тях се среща веднъж, регулярният израз работи, но щом в думата се появят два знака, системата вече не намира съвпадение за шаблона в текста.

▍Символ плюс

Знакът плюс в шаблона показва, че регулярният израз ще съвпадне със съвпадението, ако предходният знак се среща един или повече пъти в текста. В същото време такава конструкция няма да реагира на липсата на символ:

$ echo "тест" | awk "/te+st/(print $0)" $ echo "teest" | awk "/te+st/(print $0)" $ echo "tst" | awk "/te+st/(печат $0)"


Знак плюс в регулярни изрази

В този пример, ако в думата няма знак „e“, механизмът за регулярен израз няма да намери съвпадения в текста. Символът плюс също работи с класове символи - по този начин той е подобен на звездичка и въпросителен знак:

$ echo "tst" | awk "/t+st/(печат $0)" $ echo "тест" | awk "/t+st/(print $0)" $ echo "teast" | awk "/t+st/(print $0)" $ echo "teeast" | awk "/t+st/(печат $0)"


Знак плюс и класове на знаци

В този случай, ако низът съдържа символ от класа, ще се счита, че текстът съответства на шаблона.

▍ Къдрави скоби

Къдравите скоби, които могат да се използват в моделите ERE, са подобни на символите, обсъдени по-горе, но те ви позволяват да укажете по-точно необходимия брой срещания на знака, който ги предхожда. Можете да посочите лимит в два формата:
  • n - число, указващо точния брой търсени събития
  • n, m - две числа, които се тълкуват по следния начин: "поне n пъти, но не повече от m".
Ето примери за първия вариант:

$ echo "tst" | awk "/te(1)st/(print $0)" $ echo "test" | awk "/te(1)st/(print $0)"

Къдрави скоби в шаблони, намиране на точния брой срещания

В по-старите версии на awk трябваше да използвате опцията на командния ред --re-interval, за да може програмата да разпознава интервали в регулярни изрази, но в по-новите версии това не е необходимо.

$ echo "tst" | awk "/te(1,2)st/(print $0)" $ echo "test" | awk "/te(1,2)st/(print $0)" $ echo "teest" | awk "/te(1,2)st/(print $0)" $ echo "teeest" | awk "/te(1,2)st/(печат $0)"


Разстоянието е дадено във фигурни скоби

В този пример знакът "e" трябва да се появи 1 или 2 пъти в низа, тогава регулярният израз ще отговори на текста.

Къдравите скоби могат да се използват и с класове символи. Тук се прилагат вече познатите ви принципи:

$ echo "tst" | awk "/t(1,2)st/(print $0)" $ echo "test" | awk "/t(1,2)st/(print $0)" $ echo "teest" | awk "/t(1,2)st/(print $0)" $ echo "teeast" | awk "/t(1,2)st/(печат $0)"


Къдрави скоби и символни класове

Шаблонът ще реагира на текста, ако символът "a" или знакът "e" се среща веднъж или два пъти в него.

▍Логически символ „или“.

Символ | - вертикална лента, означава логическо "или" в регулярни изрази. Когато обработва регулярен израз, съдържащ няколко фрагмента, разделени от такъв знак, машината ще счита анализирания текст за съвпадение, ако съвпада с някой от фрагментите. Ето един пример:

$ echo "Това е тест" | awk "/test|exam/(print $0)" $ echo "Това е изпит" | awk "/test|exam/(print $0)" $ echo "Това е нещо друго" | awk "/тест|изпит/(печат $0)"


Булеви "или" в регулярни изрази

В този пример регулярният израз е конфигуриран да търси думите "тест" или "изпит" в текста. Обърнете внимание на факта, че между фрагментите на шаблона и символа |, който ги разделя. не трябва да има интервали.

Фрагментите от регулярен израз могат да бъдат групирани с помощта на скоби. Ако групирате определена последователност от знаци, тя ще бъде възприета от системата като нормален знак. Тоест, например, метасимволите за повторение могат да бъдат приложени към него. Ето как изглежда:

$ echo "Харесва ми" | awk "/Like(Geeks)?/(print $0)" $ echo "LikeGeeks" | awk "/Like(Geeks)?/(print $0)"


Групиране на фрагменти от регулярен израз

В тези примери думата "Geeks" е оградена в скоби, последвана от въпросителен знак. Спомнете си, че въпросителният знак означава "0 или 1 повторение", в резултат на това регулярният израз ще съответства както на низа "Like", така и на низа "LikeGeeks".

Практически примери

Сега, след като разгледахме основите на регулярните изрази, е време да направим нещо полезно с тях.

▍Преброяване на броя на файловете

Нека напишем bash скрипт, който брои файловете, разположени в директории, които са записани в променливата на средата PATH. За да направите това, първо ще трябва да формирате списък с пътища към директории. Нека направим това със sed, като заменим двоеточие с интервали:

$ echo $PATH | sed "s/:/ /g"
Командата за замяна поддържа регулярни изрази като модели за търсене на текст. В този случай всичко е изключително просто, търсим символ на двоеточие, но никой не си прави труда да използва нещо друго тук - всичко зависи от конкретната задача.
Сега трябва да преминем през получения списък в цикъл и да извършим необходимите действия, за да преброим броя на файловете там. Общата схема на скрипта ще бъде следната:

Mypath=$(echo $PATH | sed "s/:/ /g") за директория в $mypath do done
Сега нека напишем пълния текст на скрипта, като използваме командата ls, за да получим информация за броя на файловете във всяка от директориите:

#!/bin/bash mypath=$(echo $PATH | sed "s/:/ /g") count=0 за директория в $mypath do check=$(ls $directory) за елемент в $check do count=$ [ $count + 1 ] done echo "$directory - $count" count=0 done
При стартиране на скрипта може да се окаже, че някои директории от PATH не съществуват, но това няма да му попречи да преброи файловете в съществуващите директории.


Брой файлове

Основната стойност на този пример е, че с помощта на същия подход можете да решите много по-сложни проблеми. Кое зависи от вашите нужди.

▍Потвърждение на имейл адреси

Има уебсайтове с огромни колекции от регулярни изрази, които ви позволяват да проверявате адреси електронна поща, телефонни номера и т.н. Едно е обаче да вземете готово и съвсем друго да създадете нещо сами. Така че нека напишем регулярен израз за валидиране на имейл адреси. Нека започнем с анализа на първоначалните данни. Например, ето един адрес:

[имейл защитен]
Потребителското име, потребителско име, може да се състои от буквено-цифрови знаци и някои други знаци. А именно, това е точка, тире, долна черта, знак плюс. Потребителското име е последвано от знака @.

Въоръжени с тези знания, нека започнем да сглобяваме регулярния израз от лявата му страна, която служи за проверка на потребителското име. Ето какво получихме:

^(+)@
Този регулярен израз може да се чете по следния начин: "В началото на реда трябва да има поне един знак от тези в групата, дадени в квадратни скоби, а след това трябва да има знак @."

Сега това е опашката за име на хост - име на хост. Тук важат същите правила като за потребителското име, така че шаблонът за него ще изглежда така:

(+)
Името на домейн от първо ниво е предмет на специални правила. Може да има само букви, които трябва да са поне две (например такива домейни обикновено съдържат код на държава) и не повече от пет. Всичко това означава, че шаблонът за проверка на последната част от адреса ще бъде така:

\.({2,5})$
Можете да го прочетете така: "Първо трябва да има точка, след това - от 2 до 5 букви и след това редът завършва."

След като подготвихме шаблоните за отделните части на регулярния израз, нека ги сглобим:

^(+)@(+)\.({2,5})$
Сега остава само да тестваме какво се е случило:

$ехо" [имейл защитен]" | awk "/^(+)@(+)\.((2,5))$/(print $0)" $ echo " [имейл защитен]" | awk "/^(+)@(+)\.((2,5))$/(печат $0)"


Валидиране на имейл адрес с регулярни изрази

Фактът, че текстът, предаден на awk, се показва на екрана, означава, че системата го е разпознала като имейл адрес.

Резултати

Ако регулярният израз за проверка на имейл адреси, който срещнахте в самото начало на статията, изглеждаше напълно неразбираем тогава, надяваме се, че сега вече не изглежда като безсмислен набор от знаци. Ако това е вярно, тогава този материал е изпълнил целта си. Всъщност регулярните изрази са тема, с която можете да се занимавате цял живот, но дори малкото, което анализирахме, вече може да ви помогне да пишете скриптове, които обработват текстове доста напреднали.

В тази поредица от материали обикновено показвахме много прости примери за bash скриптове, които буквално се състоят от няколко реда. Нека следващия път разгледаме нещо по-голямо.

Уважаеми читатели! Използвате ли регулярни изрази, когато обработвате текст в скриптове на командния ред?

Регулярните изрази са много мощен инструмент за съвпадение на шаблони, обработка и модифициране на низове, които могат да се използват за различни задачи. Ето основните от тях:

  • Проверка на въвеждане на текст;
  • Намиране и заместване на текст във файл;
  • Пакетно преименуване на файлове;
  • Взаимодействие със услуги като Apache;
  • Проверка на низ спрямо образец.

Това не е пълен списък, регулярните изрази ви позволяват да правите много повече. Но за новите потребители те може да изглеждат твърде сложни, тъй като се използва специален език за формирането им. Но предвид мощността, която предоставя, всеки системен администратор трябва да знае и да може да използва регулярни изрази на Linux.

В тази статия ще разгледаме bash регулярните изрази за начинаещи, за да можете да разберете всички функции на този инструмент.

Два типа знаци могат да се използват в регулярни изрази:

  • редовни букви;
  • метазнаци.

Обикновените знаци са букви, цифри и препинателни знаци, които съставят всеки низ. Всички текстове са съставени от букви и можете да ги използвате в регулярни изрази, за да намерите желаната позиция в текста.

Метасимволите са нещо друго, те са това, което дава сила на регулярните изрази. С метасимволите можете да направите много повече от това да търсите единичен знак. Можете да търсите комбинации от знаци, да използвате динамичен брой знаци и да избирате диапазони. Всички специални знаци могат да бъдат разделени на два типа, това са знаци за заместване, които заместват обикновените знаци, или оператори, които показват колко пъти може да се повтори даден знак. Синтаксисът за регулярен израз би изглеждал така:

нормален_символ специален символ_оператор

замяна_на_заместващ знак специален символ_оператор

  • \ - буквалните специални символи започват с обратна наклонена черта и се използват и ако трябва да използвате специален знак под формата на препинателен знак;
  • ^ - обозначава началото на реда;
  • $ - показва края на реда;
  • * - показва, че предишният символ може да се повтори 0 или повече пъти;
  • + - показва, че предишният знак трябва да се повтори повече от един или повече пъти;
  • ? - предишният знак може да се появи нула или веднъж;
  • (н)- указва колко пъти (n) да се повтори предишният знак;
  • (n,n)- предишният символ може да се повтори от N до n пъти;
  • . - всеки символ, с изключение на подаване на ред;
  • - всеки знак, посочен в скоби;
  • x|y- знак x или знак y;
  • [^az]- всеки знак, с изключение на посочените в скоби;
  • - произволен знак от посочения диапазон;
  • [^a-z]- всеки символ, който не е в диапазона;
  • \b- обозначава граница на дума с интервал;
  • - означава, че символът трябва да е вътре в дума, например ux ще съвпада с uxb или tuxedo, но няма да съвпада с Linux;
  • - означава, че символът е цифра;
  • - нецифров знак;
  • - знак за нов ред;
  • - един от знаците за интервал, интервал, раздел и т.н.;
  • - произволен знак с изключение на интервал;
  • \T- табулатор;
  • \v- вертикален разделител;
  • \w- всеки азбучен знак, включително долна черта;
  • \W- всякакви букви, с изключение на долна черта;
  • \uXXX- символ Unicdo.

Важно е да се отбележи, че наклонена черта трябва да се използва преди буквалните специални знаци, за да се посочи, че специалният знак следва. Обратното също е вярно, ако искате да използвате специален знак, който се използва без наклонена черта като обикновен знак, тогава трябва да добавите наклонена черта.

Например искате да намерите низа 1+ 2=3 в текста. Ако използвате този низ като регулярен израз, няма да намерите нищо, защото системата интерпретира плюса като специален знак, който казва, че предишният трябва да се повтори един или повече пъти. Така че трябва да се екранира: 1 \+ 2 = 3. Без екраниране, нашият регулярен израз би съвпаднал само с низа 11=3 или 111=3 и т.н. Не е необходимо да поставяте тире пред равенството, защото това не е специален знак.

Примери за регулярен израз

Сега, след като разгледахме основите и знаете как работи всичко, остава да консолидираме придобитите знания за регулярните изрази на linux grep на практика. Два много полезни специални знака са ^ и $, които показват началото и края на реда. Например, искаме да получим всички потребители, регистрирани в нашата система, чието име започва с s. След това можете да използвате регулярния израз "^s". Можете да използвате командата egrep:

egrep "^s" /etc/passwd

Ако искаме да избираме редове по последния знак в реда, можем да използваме $. Например, нека изберем всички потребители на системата, без обвивка, записите за такива потребители завършват с false:

egrep "false$" /etc/passwd

За да покажете потребителски имена, които започват с s или d, използвайте този израз:

egrep "^" /etc/passwd

Същият резултат може да се получи с помощта на символа "|". Първият вариант е по-подходящ за диапазони, а вторият се използва по-често за обикновени или / или:

egrep "^" /etc/passwd

Сега нека изберем всички потребители, чието име не е дълго от три знака. Потребителското име завършва с двоеточие. Можем да кажем, че може да съдържа произволен азбучен знак, който трябва да се повтори три пъти, преди двоеточието:

egrep "^\w(3):" /etc/passwd

заключения

В тази статия разгледахме регулярните изрази на Linux, но това бяха само основите. Ако се задълбочите малко, ще откриете, че можете да правите много по-интересни неща с този инструмент. Времето, прекарано в изучаване на регулярни изрази, определено ще си заслужава.

В края на лекцията от Yandex за регулярните изрази:

Помощната програма grep е много мощен инструмент за търсене и филтриране. текстова информация. Тази статия показва няколко примера за неговото използване, което ще ви позволи да оцените неговите възможности.
Основната употреба на grep е да търси думи или фрази във файлове и изходни потоци. Можете да търсите, като напишете заявка и област за търсене (файл) в командния ред.
Например, за да намерите низа "needle" във файла hystack.txt, използвайте следната команда:

$ grep игла haystack.txt

В резултат на това grep ще покаже всички появявания на needle, които среща в съдържанието на файла haystack.txt. Важно е да се отбележи, че в този случай grep търси набор от знаци, а не дума. Например ще бъдат показани редове, съдържащи думата "needless" и други думи, които съдържат последователността "needle".


За да кажете на grep, че търсите конкретна дума, използвайте ключа -w. Този ключ ще ограничи търсенето само до посочената дума. Думата е заявка, ограничена от двете страни с празни знаци, препинателни знаци или нови редове.

$ grep -w игла haystack.txt

Не е нужно да ограничавате търсенето си само до един файл, grep може също да търси в група от файлове и резултатите от търсенето ще покажат файла, който съвпада. Ключът -n също ще добави номера на реда, в който е намерено съвпадение, а ключът -r ще ви позволи да извършите рекурсивно търсене. Това е много удобно при търсене сред файлове с изходни текстове на програмата.

$ grep -rnw име_на_функция /home/www/dev/myprogram/

Името на файла ще бъде посочено преди всяко съвпадение. Ако трябва да скриете имена на файлове, използвайте превключвателя -h, напротив, ако са необходими само имена на файлове, тогава посочете превключвателя -l
В следващия пример ще търсим URL адреси в IRC лог файл и ще покажем последните 10 съвпадения.

$ grep -wo http://.* channel.log | опашка

Опцията -o казва на grep да изведе само съвпадението на шаблона, а не целия ред. Изходът на grep се предава към командата tail, която отпечатва последните 10 реда по подразбиране.
Сега ще преброим броя съобщения, изпратени до irc канала от определени потребители. Например всички съобщения, които изпратих от вкъщи и от работа. Те се различават по псевдоним, вкъщи използвам псевдонима user_at_home, а на работа user_at_work.

$ grep -c "^user_at_(home|work)" channel.log

С опцията -c grep отпечатва само броя на намерените съвпадения, а не самите съвпадения. Низът за търсене е ограден в кавички, защото съдържа специални знаци, които обвивката може да разпознае като контролни знаци. Имайте предвид, че кавичките не са включени в шаблона за търсене. Обратната наклонена черта "" се използва за екраниране на служебни знаци.
Нека потърсим в съобщенията на хората, които обичат да "крещят" в канала. Под „писък“ имаме предвид съобщения, написани в рус стил, всички с ГЛАВНИ букви. За да изключим произволни попадения на съкращения от търсенето, ще търсим думи от пет или повече знака:

$ grep -w "+(5,)" channel.log

За по-подробно описание вижте man страницата на grep.
Още няколко примера:

# grep root /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin

Показва редове от файла /etc/passwd, които съдържат корена на низа.

# grep -n root /etc/passwd 1:root:x:0:0:root:/root:/bin/bash 12:operator:x:11:0:operator:/root:/sbin/nologin

Освен това се показват номерата на редовете, съдържащи низа за търсене.

# grep -v bash /etc/passwd | grep -v nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin :/sbin/halt news:x:9:13:news:/var/spool/news: mailnull:x:47:47::/var/spool/mqueue:/dev/null xfs:x:43:43: X Font Server:/etc/X11/fs:/bin/false rpc:x:32:32:Portmapper RPC потребител:/:/bin/false nscd:x:28:28:NSCD Daemon:/:/bin/false named:x:25:25:Named:/var/named:/bin/false squid:x:23:23::/var/spool/squid:/dev/null ldap:x:55:55:LDAP потребител: /var/lib/ldap:/bin/false apache:x:48:48:Apache:/var/www:/bin/false

Проверява кои потребители не използват bash, с изключение на тези потребителски акаунти, които имат nologin като своя обвивка.

# grep -c false /etc/passwd 7

Отчита броя на акаунтите, които имат /bin/false като своя обвивка.

# grep -i игри ~/.bash* | grep -v история

Тази команда изброява редове от всички файлове в домашната директория на текущия потребител, които започват с ~/.bash, с изключение на онези файлове, които имат низова история в имената си, за да изключи съвпаденията, намерени във файла ~/.bash_history, в който може да бъде един и същ низ в главни или малки букви. Моля, имайте предвид, че търсенето на думата "игри" се извършва, можете да замените всяка друга вместо това.
команда grep и регулярни изрази

За разлика от предишния пример, сега ще покажем само онези редове, които започват с низа "root":

# grep ^root /etc/passwd root:x:0:0:root:/root:/bin/bash

Ако искаме да видим кои акаунти изобщо не са използвали обвивката, търсим редове, завършващи на ":":

# grep:$ /etc/passwd news:x:9:13:news:/var/spool/news:

За да проверите дали променливата PATH във файла ~/.bashrc е експортирана, първо изберете редовете с "export" и след това потърсете редове, които започват с низа "PATH"; в този случай MANPATH и други възможни пътища няма да бъдат показани:

# grep експорт ~/.bashrc | grep "PATH" експортиране PATH="/bin:/usr/lib/mh:/lib:/usr/bin:/usr/local/bin:/usr/ucb:/usr/dbin:$PATH"

Класове на знаци

Израз в квадратни скоби е списък от знаци, затворени в знаците [" и "]"". Съвпада с всеки отделен знак в този списък; ако първият знак от списъка е "^", тогава той съответства на всеки знак, който НЕ присъства в списъка. Например регулярният израз "" съвпада с всяка една цифра.

Вътре в израз в квадратни скоби можете да посочите диапазон, състоящ се от два знака, разделени с тире. Тогава изразът съвпада с всеки отделен знак, който според правилата за сортиране попада в тези два знака, включително тези два знака; това взема предвид последователността за съпоставяне и набора от знаци, посочени в локала. Например, когато локалът по подразбиране е C, изразът "" е еквивалентен на израза "". Има много локали, където сортирането се извършва в ред на речника, и в тези локали "" обикновено не е еквивалентно на "", в тях, например, може да бъде еквивалентно на израза "". За да използвате традиционната интерпретация на израза в скоби, можете да използвате C локала, като зададете променливата на средата LC_ALL на "C".

И накрая, има класове символи, които са конкретно наименувани и са посочени в изрази в квадратни скоби. За повече информация относно тези предварително дефинирани изрази вижте man страниците или документацията за командата grep.

# grep /etc/group sys:x:3:root,bin,adm tty:x:5: mail:x:12:mail,postfix ftp:x:50: никой:x:99: дискета:x:19: xfs:x:43: nfsnobody:x:65534: postfix:x:89:

Примерът показва всички редове, които съдържат или знака "y", или знака "f".
Общи знаци (метасимволи)

Използвайте "." за съвпадение на всеки отделен знак. Ако искате да получите списък с всички английски думи, взети от речник, съдържащ пет знака, започващи с "c" и завършващи с "h" (удобно за решаване на кръстословици):

# grep " " /usr/share/dict/words catch clash cloth couch couch cough crash crush

Ако искате да покажете редове, които съдържат символ точка като литерал, използвайте опцията -F с командата grep. символи "< " и «>» означава наличието на празен низ преди и съответно след посочените букви. Това означава, че думите във файла с думи трябва да бъдат написани по подходящ начин. Ако искате да намерите всички думи в текста за посочените модели, с изключение на празните редове, пропуснете знаците "< " и «>”, за по-прецизно търсене само на думи, използвайте ключа -w.

За подобно търсене на думи, които могат да съдържат произволен брой знаци между "c" и "h", използвайте звездичка (*). Следният пример избира всички думи, започващи с "c" и завършващи с "h" от системния речник:

# grep " " /usr/share/dict/words халиф пари улов тензух гепард --изходът е пропуснат--

Ако искате да търсите буквален знак със звездичка във файл или изходен поток, използвайте единични кавички, за да го направите. Потребителят в примера по-долу първо се опитва да намери звездичка, без да използва кавички във файла /etc/profile, което не води до нищо. Когато се използват кавички, резултатът се отпечатва в изходния поток:

# grep * /etc/profile # grep "*" /etc/profile for i в /etc/profile.d/*.sh ; направи

На добър час, гости!

В днешната статия искам да засегна такава огромна тема като Регулярни изрази. Мисля, че всеки знае, че темата за регулярните изрази (както се наричат ​​регулярните изрази на жаргон) е необятна в обема на един пост. Затова ще се опитам накратко, но възможно най-ясно да събера мислите си и да ви ги предам.

Да започнем с това, че има няколко разновидности на регулярни изрази:

1. Традиционни регулярни изрази(те са основни, основни и основни регулярни изрази(BRE))

  • синтаксисът на тези изрази е дефиниран като остарял, но въпреки това все още се използва широко и се използва от много UNIX помощни програми
  • Основните регулярни изрази включват следните метасимволи (повече за техните значения по-долу):
    • \( \) - оригинал за ( ) (разширен)
    • \(\) - оригинал за () (разширен)
    • \н, където н- число от 1 до 9
  • Характеристики на използването на тези метазнаци:
    • Звездицата трябва да идва след израза, който съответства на единичния знак. Пример: *.
    • Израз \( блок\)* трябва да се считат за незаконни. В някои случаи съвпада с нула или повече повторения на низ блок. В други съвпада с низа блок* .
    • В рамките на клас знаци, стойностите на специални знаци обикновено се игнорират. Специални случаи:
    • За да добавите знак ^ към набор, той не трябва да бъде поставен първо там.
    • За да добавите символ - към набор, той трябва да бъде поставен първи или последен там. Например:
      • DNS шаблон за име, който може да включва букви, цифри, минус и разделителна точка: [-0-9a-zA-Z.] ;
      • произволен знак с изключение на минус и цифра: [^-0-9] .
    • За да добавите символ [ или ] към набор, той трябва първо да бъде поставен там. Например:
      • съвпада с ] , [ , a или b .

2. Разширени регулярни изрази(те са разширени регулярни изрази(ERE))

  • Синтаксисът на тези изрази е подобен на синтаксиса на основните изрази, с изключение на:
    • Премахнато е използването на обратни наклонени черти за метазнаци ( ) и ().
    • Обратна наклонена черта преди метасимвол отменя специалното му значение.
    • Отхвърлено теоретично нередовенстроителство \ н .
    • Добавени са метасимволи + , ? , | .

3. Съвместими с Perl регулярни изрази(те са Perl-съвместими регулярни изрази(PCRE))

  • имат по-богат, но предвидим синтаксис дори от POSIX ERE и затова често се използват от приложения.

Регулярни изрази се състои отмодели, или по-скоро задайте моделТърсене. Шаблонът се състоиот правилатърсения, които са съставени от символии метазнаци.

Правила за търсенеопределя се от следното операции:

Изброяване |

Вертикална лента (|)разделя валидните опции, можем да кажем - логическо ИЛИ. Например "сив|сив" съвпада сивоили сиво.

групиране или съюз()

Кръгли скобисе използват за определяне на обхвата и приоритета на операторите. Например "grey|grey" и "gr(a|e)y" са различни модели, но и двата описват набор, съдържащ сивои сиво.

Quantify() ? * +

Кванторслед като знак или група определя колко пъти предишенможе да се появи израз.

общ израз, повторения могат да бъдат от m до n включително.

общ израз, m или повече повторения.

общ израз, не повече от n повторения.

гладкаn повторения.

Въпросителен знакозначава 0 или 1пъти, същото като {0,1} . Например "цвят" съвпада с и цвят, и цвят.

звездаозначава 0, 1 или произволно числоведнъж ( {0,} ). Например „go*gle“ съвпада ggle, google, googleи т.н.

Плюсозначава поне 1веднъж ( {1,} ). Например „go+gle“ съвпада google, googleи т.н. (но не ggle).

Точният синтаксис за тези регулярни изрази зависи от имплементацията. (т.е. в основни регулярни изразисимволи ( и )- екранирано с обратна наклонена черта)

Метазнаци, казано по-просто, това са символи, които не отговарят на истинското им значение, тоест символ. (точка) не е точка, а всеки един знак и т.н. Моля ви да се запознаете с метасимволите и техните значения:

. отговаря сампроизволен характер
[нещо] Съответства всеки индивидзнак измежду тези, оградени в скоби. В този случай: Знакът "-" се тълкува буквално само ако се намира непосредствено след отварящата или преди затварящата скоба: или [-abc]. В противен случай той обозначава интервал от символи. Например съвпада с "a", "b" или "c". съответства на малките букви на латинската азбука. Тези обозначения могат също да се комбинират: съвпада с a, b, c, q, r, s, t, u, v, w, x, y, z. За да съвпадат знаците "[" или "]", достатъчно е, че затварящата скоба беше първият знак след отварящия знак: съвпада с "]", "[", "a" или "b". единичен знакизмежду тези които не са в скоби. Например [^abc] съответства на всеки знак, различен от "a", "b" или "c". [^a-z] съвпада с всеки знак с изключение на малки букви в латинската азбука.
^ Съвпада с началото на текст (или началото на всеки ред, ако режимът е ред по ред).
$ Съвпада с края на текста (или края на всеки ред, ако режимът е вграден).
\(\) или () Декларира "маркиран подизраз" (групиран израз), който може да се използва по-късно (вижте следващия елемент: \ н). „Маркиран подизраз“ също е „блок“. За разлика от другите оператори, този (в традиционния синтаксис) изисква обратна наклонена черта, в разширения и Perl символът \ - не е необходим.
\н Където не число от 1 до 9; отговаря нмаркиран подизраз (напр. (abcd)\0, т.е. символите abcd са маркирани с нула). Този дизайн е теоретичен нередовен, то не беше прието в синтаксиса на разширен регулярен израз.
*
  • звездаслед израз, който съвпада с един знак, съответства нулаили Повече ▼ копиятози (предходен) израз. Например "*" съвпада с празния низ, "x", "y", "zx", "zyx" и т.н.
  • \н*, където не цифра от 1 до 9, съответства на нула или повече срещания за съвпадение н-ти маркиран подизраз. Например "\(a.\)c\1*" съответства на "abcab" и "abcaba", но не и на "abcac".

Израз, ограден в "\(" и "\)" и последван от "*", трябва да се счита за невалиден. В някои случаи съвпада с нула или повече срещания на низа в скоби. В други съвпада с израза в скоби, като се има предвид знакът "*".

\{х,г\} Отговаря на последното ( предстоящи) до блок, възникващ поне хи не повече гведнъж. Например "a\(3,5\)" съвпада с "aaa", "aaaa" или "aaaaa". За разлика от другите оператори, този (в традиционния синтаксис) изисква обратна наклонена черта.
.* Означаване на произволен брой произволни знаци между две части на регулярен израз.

Метасимволите ни помагат да използваме различни съответствия. Но как метасимволът може да бъде представен от обикновен символ, тоест знакът [ (квадратна скоба) чрез стойността на квадратна скоба? Просто:

  • трябва да е предварително щит) метазнак (. * + \ ? ( )), последван от обратна наклонена черта. Например \. или \[

За да се опрости задачата на някои набори от символи, те бяха комбинирани в т.нар. класове и категории символи. POSIX стандартизира декларацията на определени класове и категории знаци, както е показано в следната таблица:

POSIX клас по същия начин обозначаване
[:горен:] главни букви
[:нисък:] малки букви
[:алфа:] главни и малки букви
[:алнум:] цифри, главни и малки букви
[:цифра:] числа
[:xdigit:] шестнадесетични цифри
[:точка:] [.,!?:…] препинателни знаци
[:празно:] [\T] интервал и TAB
[:space:] [\t\n\r\f\v] пропускане на символи
[:cntrl:] контролни символи
[:графика:] [^ \t\n\r\f\v] печатни символи
[:print:] [^\t\n\r\f\v] печат на знаци и пропускане на знаци

В regex има такова нещо като:

алчност регулярен израз

Ще се опитам да опиша възможно най-ясно. Да кажем, че искаме да намерим всички HTML тагове в някакъв текст. След като локализираме проблема, искаме да намерим стойностите между< и >, заедно с тези скоби. Но ние знаем, че таговете имат различна дължина и самите тагове са поне 50. Изброяването на всички, затварянето им в метасимволи, е твърде трудоемка задача. Но ние знаем, че имаме израз.* (звездичка точка), характеризиращ произволен брой символи в низ. Използвайки този израз, ще се опитаме да намерим в текста (

Така, Как да създадете RAID ниво 10/50 на LSI MegaRAID контролера (също приложимо за: Intel SRCU42x, Intel SRCS16):

) всички стойности между< и >. В резултат на това ЦЕЛИЯТ низ ще съответства на този израз. защо, защото регулярният израз е алчен и се опитва да улови ВСИЧКИ всички знаци между тях< и >, съответно цялата линия, започваща < p>И така...и край ...> ще принадлежи към това правило!

Надявам се от примера да стане ясно какво е алчност. За да се отървете от тази алчност, можете да отидете по следния начин:

  • разглеждайте символи, несъответстващи на желания модел (например:<[^>]*> за горния случай)
  • отървете се от алчността, като добавите дефиниция на квантор като не-алчен:
    • *? - "не алчен" ("мързелив") еквивалент *
    • +? - "не алчен" ("мързелив") еквивалент +
    • (н)? - "не алчен" ("мързелив") еквивалент на (n,)
    • .*? - "неалчен" ("мързелив") еквивалент.*

Бих искал да добавя всичко по-горе. синтаксис на разширен регулярен израз:

Регулярните изрази в POSIX са подобни на традиционния синтаксис на Unix, но с добавяне на някои метасимволи:

Плюспоказва, че предишенсимвол или Групаможе да се повтори един или повече пъти. За разлика от звездичката е необходимо поне едно повторение.

Въпросителен знакправи предишензнак или незадължителна група. С други думи, в съответния ред го може да липсва или да присъствагладка единведнъж.

вертикална лентаразделя алтернативни регулярни изрази. Един символ определя две алтернативи, но може да има повече, достатъчно е да използвате повече вертикални линии. Трябва да се помни, че този оператор използва максималната възможна част от израза. Поради тази причина алтернативният оператор най-често се използва в скоби.

Използването на обратни наклонени черти също е отхвърлено: \(…\) става (…) и \(…\) става (…).

В края на публикацията ето няколко примера за използване на регулярен израз:

$ cat text1 1 ябълка 2 круша 3 банан $ grep p text1 1 ябълка 2 круша $ grep "pp*" text1 1 ябълка 2 круша $ cat text1 | grep "l\|n" 1 ябълка 3 банан $ echo -e "намери\n* тук" | grep "\*" * тук $ grep "pl\?.*r" text1 # p, на редове с r 2 pear $ grep "a.." text1 # редове с последвано от поне 2 знака 1 ябълка 3 банан $ grep "" text1 # търсене на редове, съдържащи 3 или p 1 ябълка 2 круша 3 банан $ echo -e "намери\n* тук\nнякъде." | grep "[.*]" * тук някъде..име]$ echo -e "123\n456\n789\n0" | grep "" 123 456 789 $ sed -e "/\(a.*a\)\|\(p.*p\)/s/a/A/g" text1 # замени a с A във всички редове, където след a идва a или след p идва p 1 ябълка 2 круша 3 bAnAnA *\./ ПОСЛЕДНА ДУМА./g" Първо. ПОСЛЕДНА ДУМА. Това е ПОСЛЕДНА ДУМА.

С уважение, Mc.Sim!