Регулярное выражение
Материал из Xgu.ru
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$
Строка в кавычках: открывающая кавычка, за которой следует последовательность символов, не содержащая кавычек, после чего идет закрывающая кавычка.
"[^"]*"
[править] Программы
Программы, использующие регулярные выражения.
Некоторые из перечисленных программ являются интерпретаторами языков программирования. В этом разделе делается упор на использование однострочных программ на этих языках, другими словами, то есть на применение интерпретатора языка как ещё одной утилиты 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
[править] Рекурсивные регулярные выражения
[править] Полезные Интернет-источники и Интернет-ресурсы
- 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]
заготовки:
- http://stackoverflow.com/questions/11324749/a-regex-to-detect-string-not-enclosed-in-double-quotes/
- http://stackoverflow.com/questions/1198512/split-a-list-into-parts-based-on-a-set-of-indexes-in-python
- http://stackoverflow.com/questions/243865/how-do-i-merge-two-python-iterators
[править] Чем можно заменить negative look-behind assertions?
Вариантов несколько.
Во-первых, некоторые диалекты регулярных выражений это умеют и так. Например, умеет Perl 6 и регулярные выражения из .NET[1].
Во-вторых, инвертировать регулярное выражение и текст и использовать look-ahead assertion :)
В-третьих, ...
- Substitute for variable-length look-behind? (англ.) — обсуждение темы на PerlMonks
[править] Можно ли использовать именованные capture-группы для множественного захвата?
Можно ли сделать так, грубо говоря, чтобы получить массив или список соответствий подвыражению, находящемуся в группе захвата?
Нечто подобное есть в Perl 6 и в регулярных выражениях .NET. Подробнее: [2].
[править] Примечания
- ↑ http://oylenshpeegul.typepad.com/blog/2011/12/variable-length-look-behind-in-regular-expressions.html о negative look-behind assertions переменной длины