Original:http://gnosis.cx/publish/programming/regular_expressions.html

Публикации Дэвида Мерца * Технические публикации * Домашняя страница Gnosis Software * Моя книга: Обработка текста в Python

Купить TPiP

Введение в учебное пособие

(Переводы: Белорусский)

Предистория: эта страница, по-видимому, довольно широко читается, но только изредка получает пожертвования на вышеупомянутые ссылки. Трагедия в общинах и все такое ... но все же, если кто-нибудь из вас захочет пожертвовать доллар или два, я был бы признателен. Во всяком случае, этот учебник был впервые опубликован в IBM developerWorks. Эта версия содержит несколько незначительных исправлений, которые читатели предложили с момента публикации. Расширенную и обновленную версию можно найти в моей книге «Обработка текста в Python»

навигация

Этот учебник представляет собой только один большой HTML-файл с несколькими графиками, используемыми на этом пути. Просто прокрутите вниз, чтобы прочитать его. Печать может сломать некоторые уроки в середине - но тогда вы не заплатили много, чтобы получить это.

Для кого этот учебник?

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

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

Что же такое регулярное выражение?

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

Затруднительный комментарий программистов стоит подумать: «Иногда у вас проблемы с программированием, и кажется, что лучшим решением является использование регулярных выражений, теперь у вас есть две проблемы». Регулярные выражения удивительно мощные и глубоко выразительные. Именно поэтому их написать так же, как и с ошибкой, написать любой другой сложный программный код. Всегда проще решить действительно простую задачу простым способом; когда вы выходите за рамки простого, подумайте о регулярных выражениях.

Какие инструменты используют регулярные выражения?

Большое количество инструментов включает регулярные выражения как часть их функциональности. Unix-ориентированные средства командной строки, такие как grep , sed и awk , в основном являются оберткой для регулярной обработки выражений. Многие текстовые редакторы позволяют осуществлять поиск и / или замену на основе регулярных выражений. Многие языки программирования, особенно языки сценариев, такие как Perl, Python и TCL, создают регулярные выражения в основе языка. Даже большинство оболочек командной строки, таких как Bash или Windows-консоль, допускают ограниченные регулярные выражения как часть их синтаксиса команд.

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

Примечание по представлению

Для целей представления примеров в этом учебном пособии описанные регулярные выражения будут окружены косой чертой. Этот стиль разграничения регулярных выражений используется sed , awk , perl и другими инструментами. Например, пример может означать:

/[AZ]+(abc|xyz)*/

Читайте дальше, чтобы понять этот пример, теперь просто поймите, что фактическое регулярное выражение - это все, что есть между чертами.

Многие примеры сопровождаются иллюстрацией, которая показывает регулярное выражение, и текст, выделенный для каждого совпадения этого выражения.

контакт

Дэвид Мерц - писатель, программист и учитель, который всегда стремится улучшить свое общение с читателями (и учебниками). Он приветствует любые комментарии, направьте их на адрес <mertz@gnosis.cx>.

Куда пойти отсюда...

После того, как вы закончите этот учебник, вы увидите основы (и некоторые дополнительные темы) регулярных выражений. Лучшее, что нужно сделать дальше, - начать использовать их в реальных проблемах. Первое, на что нужно обратить внимание, - это документация, которая сопровождает конкретный инструмент, который вы используете. Кроме того, в ряде печатных книг есть хорошие объяснения регулярных выражений, часто реализуемые конкретными инструментами. Некоторые книги, созданные автором этого учебника, были следующими:

  • Освоение регулярных выражений , Фридль, Джеффри Э.Ф., О'Рейли, Кембридж, М.А. 1997.
  • sed & awk , Dale Dougherty & Arnold Robbins, O'Reilly, Cambridge, MA 1997.
  • Программирование Perl , Larry Wall, Tom Christiansen & Randal L. Schwartz, O'Reilly, Cambridge, MA 1996.
  • TCL / TK в двух словах , Пол Рейнес и Джефф Трантер, О'Рейли, Кембридж, Массачусетс, 1999.
  • Python Pocket Reference , Марк Лутц, О'Рейли, Кембридж, Массачусетс, 1998.
  • Практическое руководство по Linux , Mark G. Sobell, Addison Wesley, Reading, MA 1997.

Соответствующие шаблоны в тексте: основы


Литералы символов


/a/

Mary had a little lamb.
And everywhere that Mary
went, the lamb was sure
to go.

/Mary/

Mary had a little lamb.
And everywhere that Mary
went, the lamb was sure
to go.

    

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

Литералы «Бегство»


/.*/

Special characters must be escaped.*

/\.\*/
Special characters must be escaped.*
    

Ряд символов имеет специальные значения для регулярных выражений. Символ со специальным значением может быть сопоставлен, но для этого вы должны префикс его символом обратной косой черты (это включает сам символ обратной косой черты: чтобы соответствовать одному обратному косую черту в целевом объекте, ваше регулярное выражение должно включать «\\»).

Позиционные специальные символы


/^Mary/

Mary had a little lamb.
And everywhere that Mary
went, the lamb was sure
to go.

/Mary$/

Mary had a little lamb.
And everywhere that Mary
went, the lamb was sure
to go.

    

Два специальных символа используются почти во всех инструментах регулярного выражения, чтобы отметить начало и конец строки: caret (^) и dollarsign ($). Чтобы соответствовать карету или значению доллара как буквенному символу, вы должны избегать его (т. Е. Предшествовать ему обратным слэшем «\»).

Интересная вещь о карете и долларах заключается в том, что они соответствуют шаблонам с нулевой шириной . То есть длина строки, сопоставляемой кареткой или долларом, сама по себе равна нулю (но остальная часть регулярного выражения все равно может зависеть от соответствия нулевой ширины). Многие инструменты регулярных выражений предоставляют другой шаблон с нулевой шириной для границы слова (\ b). Слова могут быть разделены пробелами, такими как пробелы, табуляции, символы новой строки или другие символы, такие как null; шаблон слова-границы совпадает с фактической точкой, в которой начинается или заканчивается слово, а не отдельные символы пробелов.

Символ «подстановочный знак»


/^Mary/

Mary had a little lamb.
And everywhere that Mary
went, the lamb was sure
to go.

/Mary$/

Mary had a little lamb.
And everywhere that Mary
went, the lamb was sure
to go.

    

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

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

Группировка регулярных выражений


/(Mary)( )(had)/ 

Mary had a little lamb.
And everywhere that Mary
went, the lamb was sure
to go.

    

Регулярное выражение может иметь в нем буквенные символы, а также позиционные шаблоны нулевой ширины. Каждый литерал или позиционный шаблон является атомом в регулярном выражении. Вы также можете группировать несколько атомов вместе в небольшое регулярное выражение, которое является частью большего регулярного выражения. Можно было бы называть такую ​​группировку «молекулой», но обычно ее также называют атомом.

В более старых Unix-ориентированных инструментах, таких как grep , подвыражения должны быть сгруппированы с экранированными скобками, например /\(Mary\)/ . В Perl и наиболее последних инструментах (включая egrep) группировка выполняется с круглыми скобками, но для сопоставления буквенной скобки требуется экранирование в шаблоне (пример в сторону следует за Perl).

Классы символов


/[a-z]a/ 

Mary had a little lamb.
And everywhere that Mary
went, the lamb was sure
to go.

    

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

Набор символов может быть задан как простой список внутри квадратных скобок, например /[aeiou]/ будет соответствовать любому одинарному нижнему регистру. Для диапазонов букв или цифр вы также можете использовать только первую и последнюю букву диапазона с тире в середине, например /[A-Ma-m]/ будет соответствовать строчному или прописному в первой половине алфавита.

Многие инструменты регулярного выражения также предоставляют ярлыки escape-стиля для наиболее часто используемого символьного класса, такие как \s для символа пробела и \d для цифры. Вы всегда можете определить эти классы символов с квадратными скобками, но ярлыки могут сделать регулярные выражения более компактными и читаемыми.

Оператор комплемента


/[^a-z]a/ 

Mary had a little lamb.
And everywhere that Mary
went, the lamb was sure
to go.

    

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

Чередование шаблонов


/cat|dog|bird/

The pet store sold cats, dogs, and birds.

/=first|second=/

=first first= # =second second= # =first= # =second=

/(=)(first)|(second)(=)/

=first first= # =second second= # =first= # =second=

/=(first|second)=/

=first first= # =second second= # =first= # =second=

    

Использование классов символов - это способ указать, что в одном месте может произойти то или иное событие. Но что, если вы хотите указать, что одно из двух целых подвыражений происходит в позиции в регулярном выражении? Для этого вы используете оператор чередования, вертикальную полосу («|»). Это символ, который также используется для указания канала в оболочках Unix / DOS и иногда называется символом канала.

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

Базовый абстрактный квантификатор


/@(=#=)*@/ 

Match with zero in the middle: @@
Subexpresion occurs, but...: @=#=ABC@
Lots of occurrences: @=#==#==#==#==#=@
Must repeat entire pattern: @=#==#=#==#=@

    

Одна из самых мощных и распространенных вещей, которые вы можете делать с регулярными выражениями, - это указать, сколько раз атом встречается в полном регулярном выражении. Иногда вы хотите указать что-то о появлении одного символа, но очень часто вас интересует указание появления символьного класса или сгруппированного подвыражения.

Существует только один квантификатор, включенный в «основной» синтаксис регулярных выражений, звездочку («*»); на английском языке это имеет значение «некоторые или нет» или «ноль или больше». Если вы хотите указать, что любое количество атома может происходить как часть шаблона, следуйте за атомом звездочкой.

Без квантификаторов выражения группировки на самом деле не так много, но как только мы можем добавить квантификатор к подвыражению, мы можем сказать что-то о возникновении подвыражения в целом. Взгляните на пример.

Соответствующие шаблоны в тексте: промежуточный


Более абстрактные кванторы


/A+B*C?D/

AAAD
ABBBBCD
BBBCD
ABCCD
AAABBBC

    

В определенном смысле отсутствие какого-либо символа квантора после атома в любом случае количественно оценивает атом: он говорит, что атом происходит ровно один раз . Расширенные регулярные выражения (которые поддерживают большинство инструментов) добавляют еще несколько полезных чисел к «однажды точно» и «ноль или более раз». Знак плюс («+») означает «один или несколько раз», а знак вопроса («?») Означает «ноль или один раз». Эти квантификаторы на сегодняшний день являются наиболее распространенными перечислениями, которые вы вызываете именованием.

Если вы думаете об этом, вы можете видеть, что расширенные регулярные выражения фактически не позволяют вам «говорить» все, что нет у базовых. Они просто позволяют говорить об этом короче и читабельнее. Например, « (ABC)+ « эквивалентно » (ABC)(ABC)* "; и « X(ABC)?Y » эквивалентно « XABCY|XY ». Если атомы, количественно определяемые, сами являются сложными сгруппированными подвыражениями, вопросительный знак и знак плюс могут сделать вещи намного короче.

Числовые кванторы


/a{5} b{,6} c{4,8}/

aaaaa bbbbb ccccc
aaa bbb ccc
aaaaa bbbbbbbbbbbbbb ccccc

/a+ b{3,} c?/

aaaaa bbbbb ccccc
aaa bbb ccc
aaaaa bbbbbbbbbbbbbb ccccc

/a{5} b{6,} c{4,8}/

aaaaa bbbbb ccccc
aaa bbb ccc
aaaaa bbbbbbbbbbbbbb ccccc

    

Используя расширенные регулярные выражения, вы можете указать произвольные числа появления шаблонов, используя более подробный синтаксис, чем кванторы вопросительного знака, плюс-знака и звездочки. Кудрявые фигурные скобки («{» и «}») могут подсчитывать точное количество возможных случаев.

В самой общей форме квантования фигурных скобок используются два аргумента диапазона (первый должен быть не больше второго, и оба должны быть неотрицательными целыми числами). Количество инцидентов указывается таким образом, чтобы оно находилось между минимальным и максимальным указанными (включительно). Как сокращенно, любой аргумент может быть оставлен пустым: если так, минимальный / максимальный задается как нуль / бесконечность, соответственно. Если используется только один аргумент (без запятой), точно такое количество совпадений сопоставляется.

Обратные


/(abc|xyz) \1/

jkl abc xyz
jkl xyz abc
jkl abc abc
jkl xyz xyz

/(abc|xyz) (abc|xyz)/

jkl abc xyz
jkl xyz abc
jkl abc abc
jkl xyz xyz

    

Одним из мощных вариантов создания шаблонов поиска является указание, что подвыражение, которое было сопоставлено ранее в регулярном выражении, снова встречается в выражении. Мы делаем это с помощью обратных ссылок . Обратные ссылки называются цифрами от 1 до 9, которым предшествует символ обратной косой черты / escape, когда используется таким образом. Эти обратные ссылки относятся к каждой последовательной группе в шаблоне соответствия, как в /(one)(two)(three)/\1\2\3/ . Каждая пронумерованная обратная ссылка относится к группе, которая в этом примере имеет слово, соответствующее числу.

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

Обратные ссылки ссылаются на все, что происходило в предыдущих сгруппированных выражениях, в том порядке, в котором произошли эти сгруппированные выражения. Из-за соглашения об именах (\ 1- \ 9) многие инструменты ограничивают вас до девяти обратных ссылок. Некоторые инструменты позволяют фактически указывать обратные ссылки и / или сохранять их в программные переменные. Более продвинутые части этого руководства касаются этих тем

Не сопоставляйте больше, чем хотите.


/th.*s/

-- I want to match the words that start
-- with 'th' and end with 's'.
this
thus
thistle
this line matches too much

    

Квантеры в регулярных выражениях жадные . То есть, они соответствуют как можно больше.

Вероятно, самая простая ошибка при составлении регулярных выражений - слишком много . Когда вы используете квантификатор, вы хотите, чтобы он соответствовал всем (правильного сортировки) до той точки, где вы хотите закончить свое соответствие. Но при использовании «*», «+» или числовых кванторов легко забыть, что последний бит, который вы ищете, может появиться позже в строке, чем тот, который вас интересует.

Трюки для сдерживающих матчей


/th[^s]*./

-- I want to match the words that start
-- with 'th' and end with 's'.
this
thus
thistle
this line matches too much

    

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

Трюк здесь состоит в том, что есть два разных способа формулировки почти той же последовательности. Вы можете думать, что хотите сохранить совпадение, пока не дойдете до XYZ, или вы можете думать, что хотите продолжить поиск, если не дойдете до XYZ. Они немного отличаются.

Для людей, которые думали об основной вероятности, происходит одна и та же картина. Шанс прокатки 6 на кубике в одном рулоне составляет 1/6. Какова вероятность прокатки 6 в шести рулонах? Наивный расчет ставит коэффициенты при 1/6 + 1/6 + 1/6 + 1/6 + 1/6 + 1/6 или 100%. Конечно, это неправильно (в конце концов, шанс, когда двенадцать рулонов не составляет 200%). Правильный расчет: «Как мне избежать прокатки 6 на шесть рулонов?» - т.е. 5/6 * 5/6 * 5/6 * 5/6 * 5/6 * 5/6, или около 33%. Шанс получить 6 - это тот же шанс, что и избежать его (или около 66%). Фактически, если вы предполагаете переписывание серии бросков кубиков, вы можете применить регулярное выражение к письменной записи, и аналогичное мышление применяется.

Комментарии к инструментам модификации

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

Из инструментов, которые позволяют изменять текст цели, есть несколько отличий, которые нужно учитывать. То, как вы определяете замену, будет различаться между инструментами: текстовый редактор может иметь диалоговое окно; инструменты командной строки будут использовать разделители между совпадением и заменой, языки программирования обычно вызывают функции с аргументами для шаблонов соответствия и замены.

Еще одно важное различие, которое следует иметь в виду, - это то, что меняется. Unix-ориентированные средства командной строки обычно используют каналы и STDOUT для изменения буферов, а не для изменения файлов на месте. Например, команда sed будет записывать изменения в консоль, но не будет изменять исходный файл цели. Текстовые редакторы или языки программирования более склонны фактически изменять файл на месте.

Замечание о примерах модификации

В целях данного руководства примеры будут продолжать использовать разделители slash в стиле sed . В частности, в примерах указывается команда подстановки и глобальный модификатор, например, « s/this/that/g». Это выражение означает: «Заменить строку« this »на строку«, которая »всюду в целевом тексте.

Примеры состоят из команды модификации, строки ввода и выходной строки. На выходной строке будут сделаны изменения. Кроме того, каждой строке ввода / вывода будет предшествовать символ меньшего или большего размера, чтобы отличить их (порядок будет таким же, как описано), что наводит на мысль о символах перенаправления в оболочках Unix.

Пример модификации литерала


s/cat/dog/g 

< The zoo had wild dogs, bobcats, lions, and other wild cats.
> The zoo had wild dogs, bobdogs, lions, and other wild dogs.
    

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

Пример модификации шаблона соответствия


s/cat|dog/snake/g 

< The zoo had wild dogs, bobcats, lions, and other wild cats.
> The zoo had wild snakes, bobsnakes, lions, and other wild snakes.

s/[a-z]+i[a-z]*/nice/g 

< The zoo had wild dogs, bobcats, lions, and other wild cats.
> The zoo had nice dogs, bobcats, nice, and other nice cats.
    

В большинстве случаев, если вы используете регулярные выражения для изменения целевого текста, вам нужно будет сопоставить более общие шаблоны, чем просто литералы. Что бы ни было согласовано, это то, что заменяется (даже если это несколько разных строк в цели)

Модификация с использованием обратных ссылок


s/([A-Z])([0-9]{2,4}) /\2:\1 /g 

< A37 B4 C107 D54112 E1103 XXX
> 37:A B4 107:C D54112 1103:E XXX
    

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

Чтобы облегчить читаемость, подвыражения будут сгруппированы с круглыми скобками (как и с Perl), а не с экранированными скобками (как с sed ).

Другое предупреждение о несоответствии

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

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

Расширенные расширения регулярных выражений


О дополнительных функциях

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

Язык программирования Perl, вероятно, является самым сложным инструментом для обработки регулярных выражений, что объясняет большую часть его популярности. Приведенные примеры будут использовать Perl-ish-код для объяснения понятий. Другие языки программирования, особенно другие языки сценариев, такие как Python, имеют аналогичный набор улучшений. Но для целей иллюстрации синтаксис Perl наиболее точно отражает инструменты регулярного выражения, на которые он опирается, такие как ed , ex , grep , sed и awk .

Нежелательные кванторы


/th.*s/

-- I want to match the words that start
-- with 'th' and end with 's'.
this line matches just right
this # thus # thistle

/th.*?s/

-- I want to match the words that start
-- with 'th' and end with 's'.
this # thus # thistle
this line matches just right

/th.*?s /

-- I want to match the words that start
-- with 'th' and end with 's'. (FINALLY!)
this # thus # thistle
this line matches just right
    

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

Нежелательные кванторы имеют тот же синтаксис, что и обычные жадные, за исключением квантификатора, за которым следует вопросительный знак. Например, нежелательный шаблон может выглядеть так: « /A[AZ]*?B/ ". На английском языке это означает «соответствовать A, за которым следует только столько заглавных букв, сколько необходимо для поиска B.»

Одна мелочь, на которую нужно обратить внимание, заключается в том, что шаблон « /[AZ]*?./ » всегда будет соответствовать нулевым заглавным буквам. Если вы используете неживые кванторы, следите за тем, чтобы их совпадение было слишком мало , что представляет собой симметричную опасность.

Модификаторы шаблонов


/M.*[ise] /

MAINE # Massachusetts # Colorado #
mississippi # Missouri # Minnesota #

/M.*[ise] /i

MAINE # Massachusetts # Colorado #
mississippi # Missouri # Minnesota #

/M.*[ise] /gis

MAINE # Massachusetts # Colorado #
mississippi # Missouri # Minnesota #
    

В примерах модификации мы уже видели один шаблонный модификатор: модификатор g lobal. Фактически, во многих инструментах регулярных выражений мы должны были использовать модификатор «g» для всех совпадений с шаблоном. Без «g» многие инструменты будут соответствовать только первому вхождению шаблона в строке в целевом объекте. Так что это полезный модификатор (но не тот, который вы обязательно хотите использовать всегда ). Давайте посмотрим на некоторые другие.

Как небольшая мнемоника, приятно вспомнить слово «gismo» (это даже кажется подходящим). Наиболее частыми модификаторами являются:

  • g - Совпадение по всему миру
  • i - Нечувствительность к регистру
  • s - обрабатывать строку как одну строку
  • m - обрабатывать строку как несколько строк
  • o - Только шаблон компиляции один раз

Опция o - это оптимизация реализации, а не проблема регулярного выражения (но она помогает мнемонике). Параметр s- single-line позволяет подстановочному символу соответствовать символу новой строки (иначе он не будет). Опция m -line с несколькими линиями приводит к тому, что «^» и «$» соответствуют началу и концу каждой строки в цели, а не только начало / конец цели в целом (с sed или grep это значение по умолчанию). Опция i nsensitive игнорирует различия между случаем букв.

Изменение поведения обратной линии


s/([A-Z])(?:-[a-z]{3}-)([0-9]*)/\1\2/g

< A-xyz-37 # B:abcd:142 # C-wxy-66 # D-qrs-93
> A37 # B:abcd:42 # C66 # D93
    

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

Группа, которая также не должна рассматриваться как обратная ссылка, имеет столбец с вопросительным знаком в начале группы, как в « (?:pattern) ». Фактически, вы можете использовать этот синтаксис, даже если ваши обратные ссылки находятся в самом шаблоне поиска.

Именование обратных ссылок


import re
txt = "A-xyz-37 # B:abcd:142 # C-wxy-66 # D-qrs-93"
print re.sub("(?P<prefix>[A-Z])(-[a-z]{3}-)(?P<id>[0-9]*)",
             "\g<prefix>\g<id>", txt) 

A37 # B:abcd:42 # C66 # D93
    

Язык Python предлагает особенно удобный синтаксис для действительно сложных обратных ссылок. Вместо того, чтобы просто играть с нумерацией сопоставленных групп, вы можете дать им имя.

Синтаксис использования регулярных выражений в Python - это стандартный стиль / метод программирования языка программирования, а не разделители разделителей в стиле Perl или sed . Проверьте свой собственный инструмент, чтобы узнать, поддерживает ли он этот объект.

Утверждения Lookahead


s/([A-Z]-)(?=[a-z]{3})([a-z0-9]* )/\2\1/g

< A-xyz37 # B-ab6142 # C-Wxy66 # D-qrs93
> xyz37A- # B-ab6142 # C-Wxy66 # qrs93D-

s/([A-Z]-)(?![a-z]{3})([a-z0-9]* )/\2\1/g

< A-xyz37 # B-ab6142 # C-Wxy66 # D-qrs93
> A-xyz37 # ab6142B- # Wxy66C- # D-qrs93
    

Другим трюком расширенных инструментов регулярных выражений являются «утверждения с выражением». Они похожи на регулярное сгруппированное подвыражение, за исключением того, что они фактически не захватывают то, что они соответствуют. Существует два преимущества использования утверждений lookahead. С одной стороны, утверждение взгляда может функционировать аналогично группе, которая не имеет обратной привязки; то есть вы можете сопоставить что-то, не считая его в обратных ссылках. Более важно, однако, утверждение в виде заголовка может указывать на то, что следующий фрагмент шаблона имеет определенную форму, но пусть другое подвыражение фактически захватывает его (обычно для целей обратного обращения к другому подвыражению).

Существует два вида ожидающих утверждений: положительные и отрицательные. Как и следовало ожидать, положительное утверждение указывает, что что-то происходит дальше, а отрицательный указывает, что что-то не приходит дальше. Подчеркивая их связь с группами, не поддерживающими обратную связь, синтаксис для утверждений с надписью аналогичен: (?=pattern) для положительных утверждений и (?!pattern) для отрицательных утверждений.

Сделать регулярные выражения более читабельными


/               # identify URLs within a text file
          [^="] # do not match URLs in IMG tags like:
                # <img src="http://mysite.com/mypic.png">
http|ftp|gopher # make sure we find a resource type
          :\/\/ # ...needs to be followed by colon-slash-slash
      [^ \n\r]+ # stuff other than space, newline, tab is in URL
    (?=[\s\.,]) # assert: followed by whitespace/period/comma
/

The URL for my site is: http://mysite.com/mydoc.html.  You
might also enjoy ftp://yoursite.com/index.html for a good
place to download files.
    

В более поздних примерах мы начали видеть, как могут возникать сложные регулярные выражения. Эти примеры не являются их половиной. Можно сделать некоторые почти абсурдно трудно понятные вещи с регулярным выражением (но тем не менее полезными).

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

В приведенном примере используется модификатор e x tend для Perl для включения многострочных регулярных выражений с комментариями. Для получения подробной информации о том, как их составлять, обратитесь к документации для собственного инструмента.