Регулярное выражение

Материал из Xgu.ru

Перейти к: навигация, поиск
stub.png
Данная страница находится в разработке.
Эта страница ещё не закончена. Информация, представленная здесь, может оказаться неполной или неверной.

Если вы считаете, что её стоило бы доработать как можно быстрее, пожалуйста, скажите об этом.


Some people, when confronted with a problem, think,
«I know, I'll use regular expressions».
Now they have two problems.
Jamie Zawinski, August 1997

Регулярное выражение (regular expression, regexp) —

Содержание

[править] Основы

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

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

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

.
Символ. Любой символ;
\символ
Символ. Непосредственно символ следующий за экранирующей обратной косой чертой \. Например, \$ означает символ $, \^ — символ ^, \\ — символ \ ;
[...]
Символ. Символьный класс: вхождение любого символа из строки, перечисленной в квадратных скобках. Допускается указание интервала: символ1-символ2 соответствует последовательности символов, начиная с символа1 и заканчивая символом2. Если знак `-' указан в начале или конце символьного класса, он означает самого себя — символ дефиса. Инвертированный символьный класс означает наличие любого символа, кроме символов, перечисленных в его составе. Инвертированный символьный класс обозначается символом ^, следующим сразу же за открывающей квадратной скобкой. Символ ^, расположенный в любом другом месте класса не имеет никакого специального значения. Специальные символы регулярных выражений (/,*,+ и т.д.), могут быть указаны в составе символьного класса без экранирования;
^
Местоположение. Начало строки;
$
Местоположение. Конец строки;
элемент*
Повторение. Ноль или более повторений предшествующего элемента;
элемент+
Повторение. Один или более повторений предшествующего элемента;
элемент?
Повторение. Ноль или одно повторение предшествующего элемента;
элемент{n}
Повторение. Ровно n повторений предшествующего элемента.
элемент{n,m}
Повторение. От n до m повторений предшествующего элемента.
элемент1элемент2
Конкатенация. элемент1 следует за элементом2;
элемент1 | элемент2
Выбор. Присутствует элемент1 или элемент2;
( выражение )
Группировка. выражение рассматривается как один элемент;

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

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

Регулярные выражения подчиняются двум правилам:

  • При поиске строки по регулярному выражению находится первое соответствие максимальной длины;
  • Поиск является жадным или максимальным, т.е. из нескольких символьных последовательностей соответствующих заданному регулярному выражению, которые начинаются с одной позиции в тексте выбирается наибольшая (регулярное выражение (.*) выделит в строке (a+b)*c+(d+e)*f не (a+b) как можно было бы подумать, а (a+b)*c+(d+e));

Пример. Регулярные выражения

Любая последовательность символов. Символ . означает любой символ, а идущий за ним символ * означает, что предыдущий символ (.) может встретиться ноль и более раз. Таким образом, строка означает любую последовательность символов любой длины.

   .*

Строка содержащая слово linux.

   linux

Строка, содержащая слово linux и ничего кроме него, т.е. строка равная linux.

   ^linux$

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

   "[^"]*"

[править] Программы

Программы, использующие регулярные выражения.

Icon-caution.gif

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

[править] grep

[править] find

[править] expr

[править] bash

[править] sed

[править] vim

[править] awk

[править] perl

[править] python

[править] ruby

[править] Языки программирования

[править] Perl

[править] Python

[править] Ruby

[править] JavaScript

[править] Java

[править] Clojure

[править] Навороты

[править] Lookbehind- и lookahead- assertions

(?=pattern)
    is a positive look-ahead assertion
(?!pattern)
    is a negative look-ahead assertion
(?<=pattern)
    is a positive look-behind assertion
(?<!pattern)
    is a negative look-behind assertion 

[1]

[править] Рекурсивные регулярные выражения

[править] Полезные Интернет-источники и Интернет-ресурсы

  • Regexper (англ.) — визуализатор регулярных выражений
  • Истинное могущество регулярных выражений (рус.) — небольшой обзор темы контекстно-свободных и контекстно-зависимых грамматик и того, какое отношение это имеет к регулярным выражениям

[править] Литература

[править] Вопросы и ответы

[править] Как инвертировать регулярное выражение в питоне?

до куда я пока дошёл:

   >>> a='example: "quick" "brown" fox jumps "over" "the" lazy dog'
   >>> print [0] + list(itertools.chain(*[x.span() for x in re.finditer('"[^"]*"',a)])) + [-1]
   [0, 9, 16, 17, 24, 35, 41, 42, 47, -1]

заготовки:

[править] Чем можно заменить negative look-behind assertions?

Вариантов несколько.

Во-первых, некоторые диалекты регулярных выражений это умеют и так. Например, умеет Perl 6 и регулярные выражения из .NET[1].

Во-вторых, инвертировать регулярное выражение и текст и использовать look-ahead assertion :)

В-третьих, ...

[править] Можно ли использовать именованные capture-группы для множественного захвата?

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

Нечто подобное есть в Perl 6 и в регулярных выражениях .NET. Подробнее: [2].

[править] Примечания

  1. http://oylenshpeegul.typepad.com/blog/2011/12/variable-length-look-behind-in-regular-expressions.html о negative look-behind assertions переменной длины
На других языках