вторник, 10 декабря 2013 г.

Regular Expressions

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


Словосочетание «регулярные выражения», прямой перевод английского «Regular expressions», звучит довольно неуклюже.
Однако оно уже настолько прижилось, что попало в словари, поэтому придется использовать именно его – за неимением лучшего.

Регулярные выражения – это один из способов поиска подстрок (соответствий) в строках. Осуществляется это с помощью просмотра строки в поисках некоторого шаблона.
Общеизвестным примером могут быть символы «*» и «?», используемые в командной строке DOS.

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

Шаблон поиска (регулярное выражение) - это простая строка и любые символы в этой строке, которые не являются специальными (зарезервированными), считаются обычными символами.
Каждый символ регулярного выражения последовательно сравнивается с проверяемой строкой (в случае FileRenamer'а - имя файла).
Все, что не является указанными ниже спецсимволами или операторами, воспринимается, как обычный символ, рассматриваемый на простое совпадение.



Спецсимволы 

Символы ".", "|", "*", "?", "+", "(", ")", "{", "}", "[", "]", "^", "$" и "\" являются зарезервированными. Но если перед таким символом поставить "\", он становится обычным.



Универсальный символ (wildcard)

Точка "." заменяет собой любой символ, в том числе пустой.



Квантификаторы, они же умножители (Quantifiers) 

Если неизвестно, сколько именно знаков должна содержать искомая подстрока, можно использовать спецсимволы, так называемые, умножители.
Например, можно написать "hel+o", что будет означать слово, начинающееся с "He", со следующими за ним одно или несколько "l", и заканчивающееся на "о".

Вот список поддерживаемых квантификаторов:
Символ   Описание
  *      Соответствует 0 или более вхождений предшествующего выражения.
         Например, "zo*" соответствует "z" и "zoo".
  +      Соответствует 1 или более предшествующих выражений.
         Например, "zo+" соответствует "zo" и "zoo", но не "z".
  ?      Соответствует 0 или 1 предшествующих выражений.
         Например, "do(es)?" соответствует "do" в "do" или "does".
 {n}     n – неотрицательное целое. Соответствует точному количеству вхождений.
         Например, "o{2}" не найдет "o" в "Bob",но найдет два "o"" в "food".
 {n,}    n – неотрицательное целое. Соответствует вхождению, повторенному не менее n раз.
         Например, "o{2,}" не находит "o" в "Bob", зато находит все "o" в "foooood".
         "o{1,}" эквивалентно "o+". "o{0,}" эквивалентно "o*".
{n,m}    m и n – неотрицательные целые числа, где n <= m. Соответствует минимум n и
         максимум m вхождений. Например, "o{1,3}" находит три первые "o" в "fooooood".
         "o{0,1}" эквивалентно "o?". Пробел между запятой и цифрами недопустим.

Квантификаторы относятся к наиболее короткому предшествующему выражению: например, одиночный символ, набор символов или подвыражение в скобках.


Жадность

Важной особенностью квантификаторов "*" и "+" является их всеядность. Они находят все, что смогут – вместо того, что нужно.
Например, регулярное выражение "h.*o" в строке "hello out there, how are you" найдёт "hello out there, how are yo", хотя в виду, наверное, имелось "hello".
Так происходит из-за жадности регулярного выражения, ищущего не первую, а последнюю "о". Излечить квантификатор от жадности можно, добавив "?".
То есть, "h.*?o" найдёт найдет именно "hello", что и было нужно, поскольку ищет "h", за которым следует несколько произвольных символов, до первого встреченного "o".



Группировка 

Круглые скобки "(" и ")" служат двум целям - для группирования символов в подвыражения и запоминания того, что этим выражениям соответствует.
Запомненные соответствия в дальнейшем могут использоваться в строке замены, в которой \N обозначает N'ую часть соответствия.
Например, шаблон "(ab)*" найдёт всю строку "ababab", а вместо \1 будет подставлено "ab". Подвыражения нумеруются слева направо с 1 до 9, подвыражение 0 является всем шаблоном.

Если нужно сгруппировать символы, но запоминать это подвыражение не надо (например, чтобы не разбить другое подвыражение верхнего уровня), то следует использовать конструкцию (?:выражение).
Например, шаблон "(?:abc)*" не создаёт подвыражений.



Lookahead-условия

Иногда нужно сказать "найдите вот это, но только если за ним (не)стоит вот этого". Для этого используются так называемые lookahead-условия двух типов:

Положительное lookahead-условие "re1(?=re2)"
   Соответствует регулярному выражению re1, только если за ним следует выражение re2.
Отрицательное lookahead-условие "re1(?!re2)"
   Соответствует регулярному выражению re1, только если за ним не следует выражение re2.
Например, шаблон "abc(?=def)" в строке "abcdef" найдёт "abc", а в строке "abcghi" нет.


Вариации 

Символ "|" можно использовать для перебора нескольких вариантов - выражение re1|re2|re3 будет соответствовать регулярному выражению re1 или re2 или re3.
Каждый вариант - наиболее длинное предшедствующее подвыражение (поведение противоположное квантификаторам).

Примеры:
"a(b|c)" совпадёт с "ab" или "ac"
"abc|def" совпадёт с "abc" или "def".



Наборы символов (Sets) 

Используя квадратные скобки "[" и "]", можно указать группу символов (набор) для поиска.
Набор может содержать обычные символы, диапазоны символов, классы символов и классы похожих символов (equivalence classes).
С помощью конструкции "[^список]" можно указать символы, которых не должно содержаться в найденной подстроке.

Примеры:
Наборы обычных символов:
"[abc]" совпадёт с "a", "b" или "c"
"[^abc]" совпадёт с любым символом кроме "a", "b" или "c"

Диапазоны символов:
"[a-z]" совпадёт с любым символом из диапазона от "a" до "z"
"[^A-Z]" совпадёт с символом, который не лежит в диапазоне от "A" до "Z"

Классы символов указываются в наборе с помощью конструкции "[:имя_класса:]". Например, "[[:space:]]" находит любые символы пробела. В FileRenamer'е доступны следующие классы символов:
alnum    алфавитно-цифровой символ (буква, цифра)
alpha    любая буква
digit    цифра 0-9
lower    строчная (маленькая) буква
punct    символ пунктуации
space    любой символ пробела
upper    заглавная (большая) буква
xdigit   шестнадцатиричная цифра - 0-9, a-f и A-F
word     любой встречающийся в слове символ - алфавитно-цифровой и символ подчёркивания

Вместо полного названия класса символов можно использовать сокращения:
\w вместо [:word:]
\s вместо [:space:]
\d вместо [:digit:]
\l вместо [:lower:]
\u вместо [:upper:]

Для того чтобы включить символ "-" (дефис) в набор символов, поставьте его либо первым (после "[" или "[^") либо последним (перед "]"), также можно использовать escape-символ \ как в "[\-]".
Для того чтобы включить символы "[", "]" или "^" в набор символов, поставьте их в конец (перед "]") или используйте escape-символ \.



Концы и начала строк

Проверка начала или конца строки производится с помощью метасимволов ^ и $.
Например, "^thing" соответствует строке, начинающейся с "thing". "thing$" соответствует строке, заканчивающейся на "thing".

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

"\`", "\A" начало текста
"\'", "\z", "\Z" конец текста


Операторы слова

\w   символ слова (эквивалентно выражению "[[:word:]]" - буквы, цифры, "_")
\W   символ не слова (эквивалентно выражению "[^[:word:]]")
\<   начало слова (например "\   конец слова (напрмер "out\>" соответствует "out" в "shout")
\b   граница слова (либо начало, либо конец)
\B   внутри слова


Обратные ссылки 

Обратная ссылка - это ссылка на предыдущее подвыражение (группа в скобках), уже совпавшее с некоторой подстрокой; ссылка на то, что совпало, а не на само регулярное выражение.

Обратная ссылка состоит и escape-символа "\" и следующей за ним цифры от "1" до "9", "\1" ссылается на первое подвыражение, "\2" на второе и т.д.
Например, выражение "(.*)\1" совпадает со строкой составленной из двух одинаковых частей, например "abcabc" или "xyzxyz".
Обратная ссылка на подвыражение, которое ни с чем не совпало даёт пустую строку.


Символы по коду 

В шаблоне можно указать символ для поиска по его коду.
Для этого используется следующий синтаксис: escape-символ "\", за ним ноль "0" и, наконец, восьмиричный код символа.
Например, "\023" обозначает символ с восьмиричным кодом 23.
Там где может появиться двусмысленность, используйте скобки чтобы разбить выражение: "\0103" - символ с кодом 103, "(\010)3" - символ с кодом 10 за которым идёт "3".
Можно также указывать символы по их шестнадцатиричному коду. Для этого поставьте "\x" и за ним строку шестнадцатиричных цифр, опционально заключённую в {}, например, \xf0 или \x{af}


Escape-символ 

Escape-символ "\" имеет несколько значений. С помощью него обозначается операторы, например, обратные ссылки или операторы слова.
Escape-символ может делать последующий символ обычным, например, "\*" есть обычный символ "*" а не квантификатор (умножитель).

Следующие escape-последовательности представлены в основном для совместимости с Perl'ом (значения \l \L \u и \U имеют некоторые отличия):
  \w   эквивалентно [[:word:]]
  \W   эквивалентно [^[:word:]]
  \s   эквивалентно [[:space:]]
  \S   эквивалентно [^[:space:]]
  \d   эквивалентно [[:digit:]]
  \D   эквивалентно [^[:digit:]]
  \l   эквивалентно [[:lower:]]
  \L   эквивалентно [^[:lower:]]
  \u   эквивалентно [[:upper:]]
  \U   эквивалентно [^[:upper:]]
  \C   любой символ, эквивалентно "."
  \Q   начало цитаты, все символы после этого оператора
       рассматриваются как обычные пока не встретиться \E
  \E   конец цитаты, завершает последовательность, начинающуюся с \Q





Синтаксис строки замены 


Поиск с использованием регулярных выражений в FileRenamer'е предполагает замену найденного некоторой строкой. В этой строке символы "\" и "&" являются специальными,
чтобы использовать их как обычные символы поставьте впереди escape-символ "\".

В строке замены распознаются следующие специальные последовательности:

\N, где N - цифра, заменяется на N'ый компонент выражения поиска (группу в скобках)
& заменяется на всю найденную подстроку, эквивалентно \0
Эти операторы можно использовать, например, при поиске выражения и последующего изменения порядка его компонентов.
Например, введите "(Годунов) (Борис)" в поле "Заменить:" и "\2 \1" в поле "На:", чтобы найти словосочетание «Годунов Борис» и заменить его на «Борис Годунов».


Комментариев нет:

Отправить комментарий

Постоянные читатели

Популярные сообщения