Регулярные выражения b: Шпаргалка по регулярным выражениям
Шпаргалка по регулярным выражениям
Квантификаторы
Аналог | Пример | Описание | |
---|---|---|---|
? | {0,1} | a? | одно или ноль вхождений «а» |
+ | {1,} | a+ | одно или более вхождений «а» |
* | {0,} | a* | ноль или более вхождений «а» |
Модификаторы
Символ «минус» (-) меред модификатором (за исключением U) создаёт его отрицание.
Описание | |
---|---|
g | глобальный поиск (обрабатываются все совпадения с шаблоном поиска) |
i | игнорировать регистр |
m | многострочный поиск. Поясню: по умолчанию текст это одна строка, с модификатором есть отдельные строки, а значит ^ — начало строки в тексте, $ — конец строки в тексте. |
s | текст воспринимается как одна строка, спец символ «точка» (.) будет вкючать и перевод строки |
u | используется кодировка UTF-8 |
U | инвертировать жадность |
x | игнорировать все неэкранированные пробельные и перечисленные в классе символы |
Спецсимволы
Аналог | Описание | |
---|---|---|
() | подмаска, вложенное выражение | |
[] | групповой символ | |
{a,b} | количество вхождений от «a» до «b» | |
| | логическое «или», в случае с односимвольными альтернативами используйте [] | |
\ | экранирование спец символа | |
. | любой сивол, кроме перевода строки | |
\d | [0-9] | десятичная цифра |
\D | [^\d] | любой символ, кроме десятичной цифры |
\f | конец (разрыв) страницы | |
\n | перевод строки | |
\pL | буква в кодировке UTF-8 при использовании модификатора u | |
\r | возврат каретки | |
\s | [ \t\v\r\n\f] | пробельный символ |
\S | [^\s] | любой символ, кроме промельного |
\t | табуляция | |
\w | [0-9a-z_] | любая цифра, буква или знак подчеркивания |
\W | [^\w] | любой символ, кроме цифры, буквы или знака подчеркивания |
\v | вертикальная табуляция |
Спецсимволы внутри символьного класса
Пример | Описание | |
---|---|---|
^ | [^da] | отрицание, любой символ кроме «d» или «a» |
— | [a-z] | интервал, любой симво от «a» до «z» |
Позиция внутри строки
Пример | Соответствие | Описание | |
---|---|---|---|
^ | ^a | aaa aaa | начало строки |
$ | a$ | aaa aaa | конец строки |
\A | \Aa | aaa aaa aaa aaa | начало текста |
\z | a\z | aaa aaa aaa aaa | конец текста |
\b | a\b \ba | aaa aaa aaa aaa | граница слова, утверждение: предыдущий символ словесный, а следующий — нет, либо наоборот |
\B | \Ba\B | aaa aaa | отсутствие границы слова |
\G | \Ga | aaa aaa | Предыдущий успешный поиск, поиск остановился на 4-й позиции — там, где не нашлось a |
Скачать в PDF, PNG.
Якоря
Якоря в регулярных выражениях указывают на начало или конец чего-либо. Например, строки или слова. Они представлены определенными символами. К примеру, шаблон, соответствующий строке, начинающейся с цифры, должен иметь следующий вид:
^[0-9]+
Здесь символ ^
обозначает начало строки. Без него шаблон соответствовал бы любой строке, содержащей цифру.
Символьные классы
Символьные классы в регулярных выражениях соответствуют сразу некоторому набору символов. Например, \d
соответствует любой цифре от 0 до 9 включительно, \w
соответствует буквам и цифрам, а
\W
— всем символам, кроме букв и цифр. Шаблон, идентифицирующий буквы, цифры и пробел, выглядит
так:
\w\s
POSIX
POSIX — это относительно новое дополнение семейства регулярных выражений. Идея, как и в случае с символьными классами, заключается в использовании сокращений, представляющих некоторую группу символов.
Утверждения
Поначалу практически у всех возникают трудности с пониманием утверждений, однако познакомившись с ними ближе, вы будете использовать их довольно часто. Утверждения предоставляют способ сказать: «я хочу найти в этом документе каждое слово, включающее букву “q”, за которой не следует “werty”».
[^\s]*q(?!werty)[^\s]*
Приведенный выше код начинается с поиска любых символов, кроме пробела ([^\s]*
), за которыми следует
q
. Затем парсер достигает «смотрящего вперед» утверждения. Это автоматически делает предшествующий
элемент (символ, группу или символьный класс) условным — он будет соответствовать шаблону, только если
утверждение верно. В нашем случае, утверждение является отрицательным (?!
), т. е. оно будет верным,
если то, что в нем ищется, не будет найдено.
Итак, парсер проверяет несколько следующих символов по предложенному шаблону (werty
). Если они найдены,
то утверждение ложно, а значит символ q
будет «проигнорирован», т. е. не будет соответствовать шаблону.
Если же werty
не найдено, то утверждение верно, и с q
все в порядке. Затем продолжается
поиск любых символов, кроме пробела ([^\s]*
).
Кванторы
Кванторы позволяют определить часть шаблона, которая должна повторяться несколько раз подряд. Например, если вы хотите выяснить, содержит ли документ строку из от 10 до 20 (включительно) букв «a», то можно использовать этот шаблон:
a{10,20}
По умолчанию кванторы — «жадные». Поэтому квантор +
, означающий «один или больше раз», будет
соответствовать максимально возможному значению. Иногда это вызывает проблемы, и тогда вы можете сказать квантору
перестать быть жадным (стать «ленивым»), используя специальный модификатор. Посмотрите на этот код:
".*"
Этот шаблон соответствует тексту, заключенному в двойные кавычки. Однако, ваша исходная строка может быть вроде этой:
<a href="helloworld.htm" title="Привет, Мир">Привет, Мир</a>
Приведенный выше шаблон найдет в этой строке вот такую подстроку:
"helloworld.htm" title="Привет, Мир"
Он оказался слишком жадным, захватив наибольший кусок текста, который смог.
".*?"
Этот шаблон также соответствует любым символам, заключенным в двойные кавычки. Но ленивая версия (обратите внимание
на модификатор ?
) ищет наименьшее из возможных вхождений, и поэтому найдет каждую подстроку в двойных
кавычках по отдельности:
"helloworld.htm" "Привет, Мир"
Экранирование в регулярных выражениях
Регулярные выражения используют некоторые символы для обозначения различных частей шаблона. Однако, возникает
проблема, если вам нужно найти один из таких символов в строке, как обычный символ. Точка, к примеру, в регулярном
выражении обозначает «любой символ, кроме переноса строки». Если вам нужно найти точку в строке, вы не можете просто
использовать «.
» в качестве шаблона — это приведет к нахождению практически всего. Итак, вам
необходимо сообщить парсеру, что эта точка должна считаться обычной точкой, а не «любым символом». Это делается с
помощью знака экранирования.
Знак экранирования, предшествующий символу вроде точки, заставляет парсер игнорировать его функцию и считать обычным символом. Есть несколько символов, требующих такого экранирования в большинстве шаблонов и языков. Вы можете найти их в правом нижнем углу шпаргалки («Мета-символы»).
Шаблон для нахождения точки таков:
\.
Другие специальные символы в регулярных выражениях соответствуют необычным элементам в тексте. Переносы строки и табуляции, к примеру, могут быть набраны с клавиатуры, но вероятно собьют с толку языки программирования. Знак экранирования используется здесь для того, чтобы сообщить парсеру о необходимости считать следующий символ специальным, а не обычной буквой или цифрой.
Спецсимволы экранирования в регулярных выражениях
Выражение | Соответствие |
---|---|
\ | не соответствует ничему, только экранирует следующий за ним символ. Это нужно, если вы хотите ввести метасимволы !$()*+.?[\]^{|} в качестве их буквальных значений. |
\Q | не соответствует ничему, только экранирует все символы вплоть до \E |
\E | не соответствует ничему, только прекращает экранирование, начатое \Q |
Подстановка строк
Подстановка строк подробно описана в следующем параграфе «Группы и диапазоны», однако здесь следует упомянуть о существовании «пассивных» групп. Это группы, игнорируемые при подстановке, что очень полезно, если вы хотите использовать в шаблоне условие «или», но не хотите, чтобы эта группа принимала участие в подстановке.
Группы и диапазоны
Группы и диапазоны очень-очень полезны. Вероятно, проще будет начать с диапазонов. Они позволяют указать набор подходящих символов. Например, чтобы проверить, содержит ли строка шестнадцатеричные цифры (от 0 до 9 и от A до F), следует использовать такой диапазон:
[A-Fa-f0-9]
Чтобы проверить обратное, используйте отрицательный диапазон, который в нашем случае подходит под любой символ, кроме цифр от 0 до 9 и букв от A до F:
[^A-Fa-f0-9]
Группы наиболее часто применяются, когда в шаблоне необходимо условие «или»; когда нужно сослаться на часть шаблона из другой его части; а также при подстановке строк.
Использовать «или» очень просто: следующий шаблон ищет «ab» или «bc»:
(ab|bc)
Если в регулярном выражении необходимо сослаться на какую-то из предшествующих групп, следует использовать
\n
, где вместо n
подставить номер нужной группы. Вам может понадобиться шаблон,
соответствующий буквам «aaa» или «bbb», за которыми следует число, а затем те же три буквы. Такой шаблон реализуется
с помощью групп:
(aaa|bbb)[0-9]+\1
Первая часть шаблона ищет «aaa» или «bbb», объединяя найденные буквы в группу. За этим следует поиск одной или более
цифр ([0-9]+
), и наконец \1
. Последняя часть шаблона ссылается на первую группу и ищет то
же самое. Она ищет совпадение с текстом, уже найденным первой частью шаблона, а не соответствующее ему. Таким
образом, «aaa123bbb» не будет удовлетворять вышеприведенному шаблону, так как \1
будет искать «aaa»
после числа.
Одним из наиболее полезных инструментов в регулярных выражениях является подстановка строк. При замене текста можно
сослаться на найденную группу, используя $n
. Скажем, вы хотите выделить в тексте все слова «wish»
жирным начертанием. Для этого вам следует использовать функцию замены по регулярному выражению, которая может
выглядеть так:
replace(pattern, replacement, subject)
Первым параметром будет примерно такой шаблон (возможно вам понадобятся несколько дополнительных символов для этой конкретной функции):
([^A-Za-z0-9])(wish)([^A-Za-z0-9])
Он найдет любые вхождения слова «wish» вместе с предыдущим и следующим символами, если только это не буквы или цифры. Тогда ваша подстановка может быть такой:
$1<b>$2</b>$3
Ею будет заменена вся найденная по шаблону строка. Мы начинаем замену с первого найденного символа (который не буква
и не цифра), отмечая его $1
. Без этого мы бы просто удалили этот символ из текста. То же касается конца
подстановки ($3
). В середину мы добавили HTML тег для жирного начертания (разумеется, вместо него вы
можете использовать CSS или <strong>
), выделив им вторую группу, найденную по шаблону
($2
).
Модификаторы шаблонов
Модификаторы шаблонов используются в нескольких языках, в частности, в Perl. Они позволяют изменить работу парсера.
Например, модификатор i
заставляет парсер игнорировать регистры.
Регулярные выражения в Perl обрамляются одним и тем же символом в начале и в конце. Это может быть любой символ (чаще используется «/»), и выглядит все таким образом:
/pattern/
Модификаторы добавляются в конец этой строки, вот так:
/pattern/i
Мета-символы
Наконец, последняя часть таблицы содержит мета-символы. Это символы, имеющие специальное значение в регулярных выражениях. Так что если вы хотите использовать один из них как обычный символ, то его необходимо экранировать. Для проверки наличия скобки в тексте, используется такой шаблон:
\(
Шпаргалка представляет собой общее руководство по шаблонам регулярных выражений без учета специфики какого-либо языка. Она представлена в виде таблицы, помещающейся на одном печатном листе формата A4. Создана под лицензией Creative Commons на базе шпаргалки, автором которой является Dave Child. Скачать в PDF, PNG.
- Регулярные выражения
Шпаргалка по регулярным выражениям / Хабр
Доброго времени суток, друзья!
Представляю Вашему вниманию перевод статьи «Regex Cheat Sheet» автора Emma Bostian.
Регулярные выражения или «regex» используются для поиска совпадений в строке.
Ищем совпадение по шаблону
Используем метод .test()
const testString = 'My test string'
const testRegex = /string/
testRegex.test(testString) // true
Ищем совпадение по нескольким шаблонам
Используем | — альтернацию
const regex = /yes|no|maybe/
Игнорируем регистр
Используем флаг i
const caseInsensitiveRegex = /ignore case/i
const testString = 'We use the i flag to iGnOrE CasE'
caseInsensitiveRegex.test(testString) // true
Извлекаем первое совпадение в переменную
Используем метод .match()
const match = 'Hello World!'.match(/hello/i) // 'Hello'
Извлекаем все совпадения в массив
Используем флаг g
const testString = 'Repeat repeat rePeAt'
const regexWithAllMatches = /Repeat/gi
testString.match(regexWithAllMatches) // ['Repeat', 'repeat', 'rePeAt']
Ищем любой символ
Используем символ.
const regexWithWildCard = /.at/gi
const testString = 'cat BAT cupcake fAt mat dog'
const allMatchingWords = testString.match(regexWithWildCard) // ['cat', 'BAT', 'fAt', 'mat']
Ищем один вариативный символ
Используем классы, позволяющие в [ ] определять группу искомых символов
const regexWithCharClass = /[cfm]at/g
const testString = 'cat fat bat mat'
const allMatchingWords = testString.match(regexWithCharClass) // ['cat', 'fat', 'mat']
Ищем буквы алфавита
Используем диапазон [a-z]
const regexWithCharRange = /[a-e]at/
const catString = 'cat'
const batString = 'bat'
const fatString = 'fat'
regexWithCharRange.test(catString) // true
regexWithCharRange.test(batString) // true
regexWithCharRange.test(fatString) // false
Ищем определенные числа или буквы
Используем диапазон [a-z0-9]
const regexWithLetterAndNumberRange = /[a-z0-9]/ig
const testString = 'Emma19382'
testString.matсh(regexWithLetterAndNumberRange) // true
Ищем методом исключения
Для исключения ненужных символов используем символ ^ — отрицательный набор
const allCharsNotAllowed = /[^aeiou]/gi
const allCharsOrNumbersNotAllowed = /[^aeiou0-9]/gi
Ищем символы, встречающиеся в строке один или более раз
Используем символ +
const oneOrMoreAsRegex = /a+/gi
const oneOrMoreSsRegex = /s+/gi
const cityInFlorida = 'Tallahassee'
cityInFlorida.match(oneOrMoreAsRegex) // ['a', 'a', 'a']
cityInFlorida.match(oneOrMoreSsRegex) // ['ss']
Ищем символы, встречающиеся в строке ноль или более раз
Используем символ *
const zeroOrMoreOsRegex = /hi*/gi
const normalHi = 'hi'
const happyHi = 'hiiiiii'
const twoHis = 'hiihii'
const bye = 'bye'
normalHi.match(zeroOrMoreOsRegex) // ['hi']
happyHi.match(zeroOrMoreOsRegex) // ['hiiiiii']
twoHis.match(zeroOrMoreOsRegex) // ['hii', 'hii']
bye.match(zeroOrMoreOsRegex) // null
«Ленивый» поиск совпадений
Ищем наименьшую часть строки, удовлетворяющую заданному условию.
Regex по умолчанию является жадным (ищет самую длинную часть строки, удовлетворяющую условию). Используем символ?
const testString = 'catastrophe'
const greedyRegex = /c[a-z]*t/gi
const lazyRegex = /c[a-z]*?t/gi
testString.match(greedyRegex) // ['catast']
testString.match(lazyRegex) // ['cat']
Ищем с помощью стартового шаблона (шаблона начала строки)
Для поиска строки по стартовому шаблону используем символ ^ (снаружи набора символов в [ ] в отличие от отрицательного набора)
const emmaAtFrontOfString = 'Emma likes cats a lot.'
const emmaNotAtFrontOfString = 'the cats Emma likes are fluffy'
const startingStringRegex = /^Emma/
startingStringRegex.test(emmaAtFrontOfString) // true
startingStringRegex.test(emmaNotAtFrontOfString) // false
Ищем с помощью завершающего шаблона (шаблона конца строки)
Для поиска строки по завершающему шаблону используем символ $
const emmaAtBackOfString = 'The cats do not like Emma'
const emmaNotAtBackOfString = 'Emma loves the cats'
const endingStringRegex = /Emma$/
endingStringRegex.test(emmaAtBackOfString) // true
endingStringRegex.test(emmaNotAtBackOfString) // false
Ищем все буквы или числа
Используем \w
const longHand = /[A-za-z0-9_]+/
const shortHand = /\w+/
const numbers = '42'
const myFavouriteColor = 'magenta'
longHand.test(numbers) // true
shortHand.test(numbers) // true
longHand.test(myFavouriteColor) // true
shortHand.test(myFavouriteColor) // true
Ищем любые символы, за исключением букв и чисел
Используем \W
const noAlphaNumericCharRegex = /\W/gi
const weirdCharacters = '!_$!'
const alphaNumericCharacters = 'ab24EF'
noAlphaNumericCharRegex.test(weirdCharacters) // true
noAlphaNumericCharRegex.test(alphaNumericCharacters) // true
Ищем числа
Используем \d вместо [0-9]
const digitsRegex = /\d/g
const stringWithDigits = 'My cat eats $20.00 worth of food a week'
stringWithDigits.match(digitsRegex) // ['2', '0', '0', '0']
Ищем не числа
Используем \D
const nonDigitsRegex = /\D/g
const stringWithLetters = '101 degrees'
stringWithLetters.match(nonDigitsRegex) // [' ', 'd', 'e', 'g', 'r', 'e', 'e', 's']
Ищем пробелы (пробельные символы)
Используем \s
const sentenceWithWhitespace = 'I like cats!'
const spaceRegex = /\s/g
spaceRegex.match(sentenceWithWhitespace) // [' ', ' ']
Ищем любые символы, за исключением пробелов
Используем \S
const sentenceWithWhitespace = 'C a t'
const nonWhitespaceRegex = /\S/g
sentenceWithWhitespace.match(nonWhitespaceRegex) // ['C', 'a', 't']
Ищем определенное количество символов
Используем {от, до} — квантификатор
const regularHi = 'hi'
const mediocreHi = 'hiii'
const superExcitedHey = 'heeeeyyyyy!!!'
const excitedRegex = /hi{1,4}/
excitedRegex.test(regularHi) // true
excitedRegex.test(mediocreHi) // true
excitedRegex.test(superExcitedHey) // false
Ищем минимальное количество символов
Используем {от, }
const regularHi = 'hi'
const mediocreHi = 'hiii'
const superExcitedHey = 'heeeeyyyyy!!!'
const excitedRegex = /hi{2,}/
excitedRegex.test(regularHi) // false
excitedRegex.test(mediocreHi) // true
excitedRegex.test(superExcitedHey) // false
Ищем точное количество символов
Используем {число символов}
const regularHi = 'hi'
const mediocreHi = 'hiii'
const superExcitedHey = 'heeeeyyyyy!!!'
const excitedRegex = /hi{2}/
excitedRegex.test(regularHi) // false
excitedRegex.test(mediocreHi) // true
excitedRegex.test(superExcitedHey) // false
Ищем ноль или один символ
Используем ?
после искомого символа
const britishSpelling = 'colour'
const americanSpelling = 'Color'
const langRegex = /colou?r/i
langRegex.test(britishSpelling) // true
langRegex.test(americanSpelling) // true
Прим. пер.: шпаргалка от MDN.
Благодарю за потраченное время. Надеюсь, оно было потрачено не зря.
Основы регулярных выражений | Регулярные выражения
Обновл. 17 Ноя 2019 |
Регулярное выражение — это описание шаблона символов.
Вступление
Самый простой шаблон, который мы можем описать — это строка (или последовательность) символов. Например, я хочу выполнить поиск символов th
(или, если говорить более конкретно, я ищу символ t
, за которым непосредственно следует символ h
) в следующем наборе символов:
Регулярное выражение: th
Пример: There is no theory of evolution. Only a list of animals Chuck Norris allows to live.
Вы можете быть удивлены, почему не было найдено совпадение в слове There
. Дело в том, что это слово содержит заглавную букву T
, а не строчную, как в искомом регулярном выражении. Мы знаем, что это один и тот же символ, просто в другой форме. Однако это не относится к регулярным выражениям. Регулярные выражения не определяют значения искомой последовательности. Всё, что они делают — это ищут точные совпадения с тем, что описывает шаблон.
Очень простое выражение, подобное этому, на самом деле ничем не отличается от поискового запроса, который вы можете выполнить в поисковой системе (Google/Яндекс) или в вашем любимом текстовом редакторе.
Метасимволы
Символ точки (.
) является метасимволом. Метасимволы — это символы, которые имеют особое значение. Они помогают создавать более интересные шаблоны, чем просто набор конкретных символов. Практически всё, что мы будем рассматривать — будет метасимволами.
Точка (.) представляет собой любой символ. В следующем примере мы ищем символ b
, за которым следует любой символ, а за ним символ g
:
Регулярное выражение: b.g
Пример: The big bag of bits was bugged.
Важно отметить, что точка (.) соответствует только одному символу. Мы можем заставить её соответствовать более чем одному символу, используя множители, которые мы рассмотрим ниже. Кроме того, вы также можете искать несколько символов с помощью точки следующим образом:
Регулярное выражение: l..e
Пример: You can live like a king but make sure it isn't a lie.
В примере выше мы сопоставляем букву l
, за которой следуют любые два символа, и за которыми следует e
.
Диапазоны символов
Символ точки (.) позволяет нам установить соответствие любому символу. Но иногда нам необходимо быть более конкретными. В этом случае будут полезны диапазоны. Мы указываем диапазон символов, заключая их в квадратные скобки []:
Регулярное выражение: t[eo]d
Пример: When today is over Ted will have a tedious time tidying up.
В регулярном выражении выше мы ищем символ t
, за которым следует либо символ e
, либо o
, и за которым следует символ d
.
Количество символов, которые вы можете поместить в квадратные скобки, не ограничено. Вы можете разместить один символ, например, [у]
(это было бы немного глупо, но, тем не менее, это не нарушает правила), или вы можете указать несколько символов, например, [Grf4s2 # lknx]
.
Короткая запись
Допустим, мы хотим найти наличие цифр от 1 до 8. Мы могли бы использовать для поиска следующий диапазон: [12345678]
, но есть вариант получше:
Регулярное выражение: [1-8]
Пример: Room Allocations: G4 G9 F2 h2 L0 K7 M9
Вы можете комбинировать набор символов вместе с другими символами:
Регулярное выражение: [1-49]
Пример: Room Allocations: G4 G9 F2 h2 L0 K7 M9
В регулярном выражении выше мы ищем цифры 1, 2, 3, 4 или 9.
Мы также можем объединить несколько наборов. В регулярном выражении ниже мы ищем 1, 2, 3, 4, 5, a, b, c, d, e, f, x:
Регулярное выражение: [1-5a-fx]
Пример: A random set of characters: y, w, a, r, f, 4, 9, 6, 3, p, x, t
Использование наборов символов иногда может привести к странному поведению. Например, вы можете использовать диапазон [a-f]
и обнаружить, что ему соответствует символ D
. Это связано с таблицами символов, которые использует система. В большинстве системах есть таблица символов, в которой сначала идут все строчные буквы, а затем заглавные (например, abcdef .... xyzABCD ...
). Однако некоторые системы чередуют строчные и прописные буквы (например, aAbBcCdD ... yYzZ
). Если вы столкнулись с каким-то странным поведением и, при этом, используете диапазоны, то это первое, что нужно проверять.
Поиск несоответствующих символов
Иногда нам может понадобиться найти символ, который не входит в диапазон искомых. Мы можем это сделать, поместив знак вставки (^
) в начало диапазона:
Регулярное выражение: t[^eo]d
Пример: When today is over Ted will have a tedious time tidying up.
Совет: Любые символы, которые обычно имеют особое значение (метасимволы), теряют своё особое значение и становятся обычными символами, находясь внутри диапазона. Исключением является знак вставки (^), который приобретает новое значение — отрицание.
Мультипликаторы
Мультипликаторы позволяют увеличить количество раз, когда элемент может появиться в нашем регулярном выражении. Вот основной набор мультипликаторов:
*
— значение встречается 0 или более раз.
+
— значение встречается 1 или несколько раз.
?
— значение встречается 0 или 1 раз.
{5}
— значение встречается 5 раз.
{3,7}
— значение встречается от 3 до 7 раз.
{2,}
— значение встречается не менее 2 раз.
Их действие распространяется на всё, что находится прямо перед ними. Это может быть обычный символ, например:
Регулярное выражение: lo*
Пример: Are you looking at the lock or the silk?
В примере выше мы ищем символ l
, за которым следует символ o
ноль или более раз. Вот почему l
в слове silk
также является совпадением (это l
, за которым идёт символ o
ноль раз).
Или это может быть метасимвол, например:
Регулярное выражение: l.*k
Пример: Are you looking at the lock or the silk?
На первый взгляд такой результат может показаться вам немного странным. Регулярное выражение .*
соответствует повторению ноль или более раз любого символа. Вы могли бы подумать, что при нахождении первого k
, будет сказано «да, я нашёл совпадение», но на самом деле говориться, что «k
является любым символом, поэтому давайте посмотрим, на сколько длинным может быть соответствие», и поиск продолжится, пока не будет найдет последний k
в строке.
Это то, что называется жадным сопоставлением. Это нормальное поведение — пытаться найти самую большую строку, которая может соответствовать шаблону. Мы можем изменить это поведение и сделать его не жадным, поместив вопросительный знак (?
) после мультипликатора (что может показаться немного запутанным, поскольку вопросительный знак сам по себе является множителем):
Регулярное выражение: l.*?k
Пример: Are you looking at the lock or the silk?
Экранирование
Иногда нам может потребоваться найти один из символов, который является метасимволом. Для этого мы используем то, что называется экранированием. Поместив обратную косую черту (\) перед метасимволом, мы можем удалить его особое значение. Допустим, что нам нужно найти появление слова this
, которое является последним словом в предложении.
Если бы мы сделали следующее:
Регулярное выражение: this.
Пример: Surely this regular expression should match this.
То нашли бы this.
как в конце предложения, так и в начале, потому что точка в регулярном выражении обычно соответствует любому символу.
Решением будет следующее:
Регулярное выражение: this\.
Пример: Surely this regular expression should match this.
Совет: Когда метасимволы являются частью вашей искомой строки, то очень легко забыть об их экранировании. Если в результатах ваших регулярных выражений что-то не то, то внимательно обследуйте метасимволы, которые вы, возможно, забыли экранировать.
Механизм работы регулярных выражений
Теперь, когда у вас есть представление о том, что такое регулярные выражения, мы можем рассмотреть то, что происходит под капотом.
Итак, мы имеем указатель, который постепенно перемещается по строке поиска. Как только он сталкивается с символом, который соответствует началу регулярного выражения, он останавливается. Теперь запускается второй указатель, который перемещается вперёд от первого указателя, символ за символом, проверяя с каждым шагом, сохраняется ли соответствие шаблону или нет. Если мы доберёмся до конца шаблона и сохраняется соответствие, то мы нашли совпадение. Если на любом шаге происходит сбой, второй указатель отбрасывается, а основной указатель продолжает движение по строке.
Заключение
Резюмируем то, что мы узнали:
.
— соответствует любому символу;
[ ]
— совпадает с символом из диапазона, содержащегося в квадратных скобках;
[^]
— соответствует символам, которые не входят в диапазон, содержащийся в квадратных скобках;
*
— совпадение 0 или более раз с указанным элементом;
+
— совпадение 1 или более раз с указанным элементом;
?
— совпадение 0 или 1 раз с указанным элементом;
{n}
— точное совпадение n раз указанного элемента;
{n, m}
— точное совпадение от n до m раз указанного элемента;
{n, }
— точное совпадение n или более раз указанного элемента;
\
— экранирование или отмена специального значения указанного символа.
Оценить статью:
Загрузка…
Поделиться в социальных сетях:
Регулярные выражения, пособие для новичков. Часть 2 / Хабр
В первой половине этого пособия мы раскрыли лишь малую часть возможностей регулярных выражений. Во второй, большей, половине мы рассмотрим некоторые новые метасимволы, то, как использовать группы для получения частей совпавшего текста, разбивать строки, находить и замещать части текста. В конце немного поговорим о распространенных ошибках.
Больше метасимволов
Есть некоторые метасимволы, которые мы еще не изучили. Большинство из них будут рассмотрены в этом разделе.
Некоторые из оставшихся метасимволов являются утверждениями нулевого размера. Они не вызывают движок для прохода по строке, они вообще не охватывают никаких символов, возможен просто успех или неудача. Например, \b
это утверждение о том, что текущая позиция находится на границе (boundary) слова, при этом сам символ \b
не изменяет позицию. Это означает, что утверждения нулевого размера никогда не должны повторяться, потому что, если они совпали один раз в данном месте, они, очевидно, будут соответствовать этому месту бесконечное число раз.
|
Соответствует оператору ИЛИ. Если А и В являются регулярными выражениями, то A|B
будет соответствовать любая строка, которая соответствует А или В. Метасимвол |
имеет очень низкий приоритет для того, чтобы заставить его работать разумно, когда вы чередуете несколько символов строки. Crow|Servo будет искать соответствие либо Crow
, либо Servo
, а не Cro('w' или 'S')ervo
.
^
Ищет соответствие только в начале строки. Если включен флаг MULTILINE
, как говорилось в прошлой части, то происходит сравнение и для каждой части после символа новой строки.
Например, если вы хотите найти только те строки, у которых в начале имеется From
, то в регулярном выражении записывается ^From
:
>>> print re.search(‘^From’, ‘From Here to Eternity’)
<_sre.SRE_Match object at 0x…>
>>> print re.search(‘^From’, ‘Reciting From Memory’)
None
$
То же, что ^
, но в конце строки, которая определяется либо, собственно по концу строки как таковому, либо по символу новой строки.
>>> print re.search(‘}$’, ‘{block}’)
<_sre.SRE_Match object at 0x…>
>>> print re.search(‘}$’, ‘{block} ‘)
None
>>> print re.search(‘}$’, ‘{block}\n’)
<_sre.SRE_Match object at 0x…>
\A
Совпадение только в начале строки, то есть тоже, что ^
, но не зависит от флага MULTILINE
\Z
Совпадение только в конце строки, то есть тоже, что $
, но не зависит от флага MULTILINE
\b
Граница слова. Слово определяется как последовательность символов чисел и/или букв, так что границы слова представляют пробелы или любые символы, не относящиеся к перечисленным.
Следующий пример ищет слово class
только когда это отдельное слово. Если оно содержится внутри другого слова, соответствия не находится:
>>> p = re.compile(r’\bclass\b’)
>>> print p.search(‘no class at all’)
<_sre.SRE_Match object at 0x…>
>>> print p.search(‘the declassified algorithm’)
None
>>> print p.search(‘one subclass is’)
None
Есть две тонкости, которые вы должны помнить при использовании этой специальной последовательности. Во-первых, это одно из худших столкновений между строковыми литералами Python и последовательностями регулярных выражений: в строковых литералах Python, \b
это символ backspace, ASCII значение 8. Если не использовать «сырые» строки, Python будет конвертировать \b
в backspace, и ваше регулярное выражение будет не таким, как задумано:
>>> p = re.compile(‘\bclass\b’)
>>> print p.search(‘no class at all’)
None
>>> print p.search(‘\b’ + ‘class’ + ‘\b’)
<_sre.SRE_Match object at 0x…>
Во-вторых, внутри класса символов нельзя использовать данное сочетание, потому как сочетание \b
для совместимости со строковыми литералами Python представляет символ backspace.
\B
Противоположное предыдущему сочетание, соответствующая текущей позиции не на границе слова.
Группировка
Часто необходимо получить больше информации, чем просто узнать, находит ли РВ соответствие или нет. Регулярные выражения часто используются для разрезания строк написанием регулярных выражений, разделенных на несколько подгрупп, которые соответствуют различным компонентам запроса. Например, в стандарте RFC-822 в заголовке имеются различные поля, разделенные двоеточием:
From: [email protected]
User-Agent: Thunderbird 1.5.0.9 (X11/20061227)
MIME-Version: 1.0
To: [email protected]
Это может быть обработано написанием регулярного выражения, которое соответствует всей строке заголовка, и в нем есть одна группа, которая соответствует имени заголовка, и другая группа, которая соответствует значению заголовка.
Группы обозначаются метасимволами в виде круглых скобок '(', ')'
. '('
и ')'
имеют такой же смысл, как в математических выражениях; они группируют вместе выражения, содержащиеся в них, и вы можете повторять содержание группы повторяющими квалификаторами, такими как *, +, ?
и {m, n}
. Например, (ab)*
будет соответствовать нулю или более повторений ab
.
>>> p = re.compile(‘(ab)*’)
>>> print p.match(‘ababababab’).span()
(0, 10)
Группы, определяемые скобками, также захватывают начальные и конечные индексы совпадающего текста; это может быть получено передачей аргумента group(), start(), end()
и span()
. Группы нумеруются, начина с 0. Группа 0 имеется всегда, это само регулярное выражение целиком, так что методы MatchObject
всегда содержат 0 как аргумент по умолчанию:
>>> p = re.compile(‘(a)b’)
>>> m = p.match(‘ab’)
>>> m.group()
‘ab’
>>> m.group(0)
‘ab’
Подгруппы нумеруются слева направо, от 1 и далее. Группы могут быть вложенными; для того чтобы определить число вложений, просто подсчитываем слева направо символы открывающей скобки:
>>> p = re.compile(‘(a(b)c)d’)
>>> m = p.match(‘abcd’)
>>> m.group(0)
‘abcd’
>>> m.group(1)
‘abc’
>>> m.group(2)
‘b’
group()
может принять одновременно несколько номеров групп в одном запросе, и будет возвращен кортеж, содержащий значения для соответствующих групп:
>>> m.group(2,1,2)
(‘b’, ‘abc’, ‘b’)
Метод groups()
возвращает кортеж строк для всех подгрупп, начиная с 1-ой:
>>> m.groups()
(‘abc’, ‘b’)
Обратные ссылки в шаблоне позволяют вам указать, что содержание ранее захваченной группы также должно быть найдено в текущей позиции строки. Например, \1
соответствует тому, что содержание группы 1 в точности повторяется в текущей позиции.
Например, следующее РВ обнаруживает в строке дважды подряд повторяющиеся слова:
>>> p = re.compile(r'(\b\w+)\s+\1′)
>>> p.search(‘Paris in the the spring’).group()
‘the the’
Обратные ссылки, такие, как эта, не часто бывают полезны для поиска по строке, но вы скоро узнаете, что они очень полезны при выполнении замены строки.
Группы с захватом содержимого и именованные группы
Регулярные выражения могут использовать множество групп, как для захвата необходимой подстроки, так и для группировки и структурирования самих РВ. В сложных регулярных выражениях становится трудно отслеживать номера групп. Есть две особенности, которые помогают справиться с этой проблемой. Обе из них используют общий синтаксис для расширения регулярных выражений, который мы поэтому и рассмотрим сначала.
В Perl 5 было добавлено несколько дополнительных функций для стандартных регулярных выражений, и модуль re
поддерживает большинство из них. Было бы сложно выбрать новые односимвольные метасимволы или новые последовательности с бэкслешем, для того чтобы представить новые особенности так, чтобы регулярные выражения Perl без путаницы отличались от стандартных регулярных выражений. Если выбрать в качестве нового метасимвола, например, &
, то старые регулярные выражения принимали бы его как обычный символ и нельзя было бы экранировать его \&
или [&]
.
Решение, выбранное разработчиками Perl состояло в том, чтобы использовать в качестве расширения синтаксиса (?...)
. Знак вопроса после скобки в случае обычного РВ это синтаксическая ошибка, поскольку ?
нечего повторять, так что это не приводит к каким-либо проблемам в совместимости. Символы сразу после ?
показывают какое расширение используется, так (?=foo)
это одно (положительное утверждение о предпросмотре), а (?:foo)
это что-то другое (группа без захвата содержимого, включающая подвыражение foo
).
К расширенному синтаксису Perl в Python добавляется собственное расширение. Если первый символ после знака вопроса P
, то это означает что используется расширение, специфичное для Python. В настоящее время существуют два таких расширения: (?P<some_name>...
)определяет именованную группу, а (?P=some_name
) служит для нее обратной ссылкой. Если в будущих версиях Perl 5 добавятся аналогичные возможности, использующие другой синтаксис, модуль re
будет изменен для поддержки нового синтаксиса, сохраняя при этом для совместимости Python-синтаксис.
Иногда вам нужно использовать группу для сбора части регулярного выражения, но вы не заинтересованы в извлечении содержимого группы. Вы можете сделать это, используя группу без захвата содержимого: (?:...)
, где вы можете заменить ...
любым другим регулярным выражением:
>>> m = re.match(«([abc])+», «abc»)
>>> m.groups()
(‘c’,)
>>> m = re.match(«(?:[abc])+», «abc»)
>>> m.groups()
()
За исключением того, что вы не получаете содержимого того, с чем совпала группа, эти группы ведут себя также, как и обычные; вы можете в них поместить что угодно, повторить с помощью соответствующего символа, такого как *
, и вставить их в другие группы (собирающие данные или нет).
Более важной особенностью являются именованные группы: вместо ссылки на них по номерам, на эти группы можно ссылаться по имени.
Синтаксис именованных групп это одно из специфичных Python-расширений: (?P<some_name>...)
. Именованные группы ведут себя в точности как обычные, но вдобавок к этому ассоциируются с каким-то именем. Методы MatchObject
, которые использовались для обычных групп принимают как числа, ссылающиеся на номер группы, так и строки, содержащие имя необходимой группы. То есть именованные группы все также принимают и числа, так что вы можете получить информацию о группе двумя способами:
>>> p = re.compile(r'(?P<word>\b\w+\b)’)
>>> m = p.search( ‘(((( Lots of punctuation )))’ )
>>> m.group(‘word’)
‘Lots’
>>> m.group(1)
‘Lots’
Именованные группы удобны тем, что они позволяют использовать вместо цифр легко запоминающиеся имена. Вот пример регулярного выражения из модуля imaplib
:
InternalDate = re.compile(r’INTERNALDATE «‘
r'(?P<day>[ 123][0-9])-(?P<mon>[A-Z][a-z][a-z])-‘
r'(?P<year>[0-9][0-9][0-9][0-9])’
r’ (?P<hour>[0-9][0-9]):(?P<min>[0-9][0-9]):(?P<sec>[0-9][0-9])’
r’ (?P<zonen>[-+])(?P<zoneh>[0-9][0-9])(?P<zonem>[0-9][0-9])’
r'»‘)
Синтаксис обратных ссылок в регулярном выражение типа (...)\1
ссылается на номер группы. Более естественно было бы использовать вместо номеров имена групп. Другое Python расширение: (?P=name)
показывает, что содержимое названной группы снова должно быть сопоставлено в текущей позиции. Наше прежнее регулярное выражение для поиска дублирующихся слов, (\b\w+)\s+\1
может быть также записано как (?P<doble_word>\b\w+)\s+(?P=doble_word)
:
>>> p = re.compile(r'(?P<word>\b\w+)\s+(?P=word)’)
>>> p.search(‘Paris in the the spring’).group()
‘the the’
Опережающие проверки
Проверки доступны в позитивной и негативной (ретроспективной) форме, и выглядят так:
(?=...)
Положительная проверка. Соответствует случаю, когда содержащееся выражение, представленное здесь как ...
, соответствует текущей позиции. Но, после того как содержащееся выражение было опробовано, сравнивающий движок не продвигается далее; остаток шаблона сравнивается далее справа от того места, где начинается утверждение.
(?!...)
Отрицательное проверка соответствует случаю, когда содержащиеся выражение не соответствует текущей позиции строки.
Для конкретики, рассмотрим случай, в котором полезен предпросмотр. Рассмотрим простой шаблон для сравнения имени файла и разбиения его на части: само имя и расширение, отделенные друг от друга точкой.
Шаблон для такого сравнения довольно прост:
.*[.].*$
Отметим, что символ .
требует специальных скобок, поскольку сама точка является метасимволом, что видно в этом же выражении. Также отметим заключительный $; он добавлен для того, чтобы обеспечить включение в расширение всего остатка строки.
Теперь, рассмотрим проблему немного шире; что, если вы хотите сравнить имена всех файлов, у которых расширение не bat
? Несколько неверных попыток:
.*[.][^b].*$
Первая попытка состоит в том, чтобы исключить bat
требованием, чтобы первый символ расширение был не b
. Это неправильно, потому что шаблон также исключит foo.bar
.
.*[.]([^b]..|.[^a].|..[^t])$
Выражение получится еще неряшливее, когда вы решите подправить первое решение отдельным заданием нужных символов: первый символ расширения должен быть не b; второй — не a; третий — не t. Это позволит включить foo.bar
и отклонить autoexec.bat
, но требует расширения из трех букв и не будет работать с двухсимвольными расширениями имен файлов, наприме sendmail.cf
. Тогда нам придется снова усложнить шаблон, чтобы решить эту проблему:
.*[.]([^b].?.?|.[^a]?.?|..?[^t]?)$
В третьей попытке, вторая и третья буквы для того, чтобы позволить сравнение расширений, короче чем три символа, сделаны необязательными.
Шаблон теперь действительно готов, его сложно читать и понимать. Еще хуже, если изменится проблема и вам нужно будет исключить и bat, и exe расширения, шаблон станет еще более сложным и запутанным.
Негативная опережающая проверка решает все эти затруднения:
.*[.](?!bat$).*$
Отрицательный предпросмотр означает: если выражение bat
не соответствует данной позиции, сравнить остаток шаблона; если обнаружено соответствие bat$
, то весь шаблон нам не подходит. Заключающий выражение знак $
нужен для того, чтобы было разрешено и такое выражение, как sample.batch
.
Исключить другое расширение теперь тоже легко; просто добавляем его как альтернативное в том же утверждении. Следующий шаблон исключает имена файлов, которые заканчиваются расширением bat
или exe
:
.*[.](?!bat$|exe$).*$
Изменение строк
До этого момента, мы просто выполняли поиск по статической строке. Регулярные выражения также часто используется для изменения строк различными способами, используя следующие методы шаблонов:
Метод/атрибут | Цель |
split() | Разбить строку в список там, где есть совпадение РВ |
sub() | Найти все подстроки совпадений с РВ и заменить их другой строкой |
subn() | Делает то же, что и sub(), но возвращает новую строку и число замещений |
Разбиение строк
Метод шаблона split()
разбивает строку на части там, где есть совпадение РВ, возвращая список частей. Это похоже на строковый метод split()
, но обеспечивает всеобщность в разделителях, по которым происходит разбиение; обычный split()
обеспечивает разбиение только по whitespace-символам или фиксированной строке. Как и следовало ожидать, существует и модульная функция re.split()
.
.split(string[, maxsplit=0])
Разбивает строку по совпадениям с регулярным выражением. Если в РВ имеются захватывающие скобки, то их содержание также будет возвращаться как часть полученного списка. Если maxsplit
не ноль, выполняется не более, чем maxsplit
разбиений, остаток строки будет возвращен как последний элемент списка.
В следующем примере разделителем является любая последовательность небуквенно-цифровых символов.
>>> p = re.compile(r’\W+’)
>>> p.split(‘This is a test, short and sweet, of split().’)
[‘This’, ‘is’, ‘a’, ‘test’, ‘short’, ‘and’, ‘sweet’, ‘of’, ‘split’, »]
>>> p.split(‘This is a test, short and sweet, of split().’, 3)
[‘This’, ‘is’, ‘a’, ‘test, short and sweet, of split().’]
Иногда вы заинтересованы не только в том, какой текст был между разделителями, но также должны знать, какой разделитель использовался. Если в РВ есть захватывающие скобки, то и эти значения также возвращаются, как часть списка. Сравните:
>>> p = re.compile(r’\W+’)
>>> p2 = re.compile(r'(\W+)’)
>>> p.split(‘This… is a test.’)
[‘This’, ‘is’, ‘a’, ‘test’, »]
>>> p2.split(‘This… is a test.’)
[‘This’, ‘… ‘, ‘is’, ‘ ‘, ‘a’, ‘ ‘, ‘test’, ‘.’, »]
Функция модуля re.split()
в качестве первого аргумента забирает РВ, а в остальном ведет себя также:
>>> re.split(‘[\W]+’, ‘Words, words, words.’)
[‘Words’, ‘words’, ‘words’, »]
>>> re.split(‘([\W]+)’, ‘Words, words, words.’)
[‘Words’, ‘, ‘, ‘words’, ‘, ‘, ‘words’, ‘.’, »]
>>> re.split(‘[\W]+’, ‘Words, words, words.’, 1)
[‘Words’, ‘words, words.’]
Поиск и замена
Другая распространенная задача — найти все совпадения с шаблоном и заменить их другой строкой. Метод sub()
берет в качестве аргументов значение замещающей части (которая может быть как строкой, так и функцией) и строку, которая должна быть обработана.
.sub(replacement, string[, count=0])
Возвращает строку, получающуюся при замене. Если шаблон не найден строка возвращается неизменной.
Добавочный аргумент count
это максимальное число замещаемых совпадений.
Простой пример использования метода sub()
. Названия цветов замещаются словом colour
:
>>> p = re.compile( ‘(blue|white|red)’)
>>> p.sub(‘colour’, ‘blue socks and red shoes’)
‘colour socks and colour shoes’
>>> p.sub(‘colour’, ‘blue socks and red shoes’, count=1)
‘colour socks and red shoes’
Метод subn() делает то же самое, но возвращает кортеж, содержащий новую строку и число произведенных замен:
>>> p = re.compile( ‘(blue|white|red)’)
>>> p.subn( ‘colour’, ‘blue socks and red shoes’)
(‘colour socks and colour shoes’, 2)
>>> p.subn( ‘colour’, ‘no colours at all’)
(‘no colours at all’, 0)
Пустые совпадения заменяются только тогда, когда они не смежны с предыдущим совпадением:
>>> p = re.compile(‘x*’)
>>> p.sub(‘-‘, ‘abxd’)
‘-a-b-d-‘
Если заместителем служит строка, то в ней поддерживаются символы экранирования. Так, \n
это одиночный символ новой строки, \r
это возврат каретки и так далее. Обратные ссылки, такие как \6
замещаются подстрокой, совпавшей с соответствующей группой в РВ. Это позволяет вам включать части оригинального текста в результат замены строки.
Пример соответствует слову section
в части строки, предшествующей части в фигурных скобках {, }
, и заменяет section
на subsection
:
>>> p = re.compile(‘section{ ( [^}]* ) }’, re.VERBOSE)
>>> p.sub(r’subsection{\1}’,’section{First} section{second}’)
‘subsection{First} subsection{second}’
Также имеется возможность ссылаться на именованные группы. Для этого используется последовательность \g<...>
, где в качестве ...
может выступать номер или имя группы. \g<2>
это эквивалент \2
, но он не двусмыслен в таких заместителях, как \g<2>0
. (\20
будет интерпретироваться как ссылка на группу 20, а не как вторую группу с последующим литералом ‘0’.) Следующие операции эквиваленты, но используют три различных способа:
>>> p = re.compile(‘section{ (?P<name> [^}]* ) }’, re.VERBOSE)
>>> p.sub(r’subsection{\1}’,’section{First}’)
‘subsection{First}’
>>> p.sub(r’subsection{\g<1>}’,’section{First}’)
‘subsection{First}’
>>> p.sub(r’subsection{\g<name>}’,’section{First}’)
‘subsection{First}’
Заместитель также может быть и функцией, дающем вам больше возможностей управления. Если это так, функция вызывается для каждого случая неперекрытия шаблона. При каждом вызове функции передается в качестве аргумента MatchObject
.
В следующем примере функция замены переводит десятичные числа в шестнадцатеричные:
>>> def hexrepl( match ):
… «Return the hex string for a decimal number»
… value = int( match.group() )
… return hex(value)
…
>>> p = re.compile(r’\d+’)
>>> p.sub(hexrepl, ‘Call 65490 for printing, 49152 for user code.’)
‘Call 0xffd2 for printing, 0xc000 for user code.’
Общие проблемы
Регулярные выражения это мощный инструмент для некоторых применений, но в некоторых отношениях их поведение не интуитивно, а иногда они не ведут себя так, как вы ожидаете от них. В этом разделе будет указано на некоторые из наиболее распространенных ошибок.
Использование строковых методов
Иногда использование модуля re
это ошибка. Если вы ищете фиксированную строку или одиночный символ, и вам не нужно использовать никаких особенностей re
, то и вся мощь регулярных выражения для этого не требуется. У строк есть несколько методов для операций с фиксированными строками и они обычно гораздо быстрее, потому что оптимизированы для этой цели.
Представим, нужно заменить одну фиксированную строку другой, например, заменить слово word
словом deed
. Здесь, конечно, подойдет функция re.sub()
, но рассмотрим строковый метод replace()
. Отметим, что replace()
будет также заменять word
внутри слов, меняя swordfish
на sdeedfish
, но и простецкое регулярное выражение будет делать это то же. (Чтобы избежать выполнения замещения на части слов, шаблон должен содержать \bword\b
).
Другая распространенная задача это удаление одиночного символа из строки или замена его другим символом. Вы можете сделать это чем-то вроде re.sub('\n', ' ', S)
, но метод translate() справится с обеими задачами и сделает это быстрее, чем любое регулярное выражение.
Короче говоря, прежде чем использовать модуль re
, посмотрите, может ли проблема быть решена более быстрыми и простыми методами строк.
match() в сравнении с search()
Функция match()
ищет соответствие РВ в начале строки, тогда как search()
ищет соответствие во всей строке. Важно иметь в виду это различие:
>>> print re.match(‘super’, ‘superstition’).span()
(0, 5)
>>> print re.match(‘super’, ‘insuperable’)
None
>>> print re.search(‘super’, ‘superstition’).span()
(0, 5)
>>> print re.search(‘super’, ‘insuperable’).span()
(2, 7)
У вас может возникнуть соблазн всегда пользоваться re.match()
, просто добавляя перед вашим регулярным выражением .*
. Сопротивляйтесь этому искушению, и вместо этого используйте re.search()
. Компилятор регулярных выражений производит небольшой анализ РВ для того, чтобы ускорить процесс поиска соответствия. Один из видов такого анализа заключается в определении того, что должно быть первым символом совпадения, например, совпадение с шаблоном, начинающимся с Crow
, должно начинаться с 'C'
. Этот анализ приводит к тому, что движок быстро пробегает строку в поиске начального символа, и начинает полное сравнение только, если найден символ ‘C’.
Добавление .*
сводит на нет эту оптимизацию, требуя сканирования до конца строки, а затем возвращения, чтобы сравнить остаток регулярного выражения. Используйте вместо этого re.search()
.
Жадный против нежадного
При повторении в РВ, таком как a*
, результирующее действие съедает настолько большую часть шаблона, насколько это возможно. На этом часто обжигаются те, кто хочет найти пару симметричных определителей, таких как угловые скобки , окружающие HTML-теги. Наивный подход к шаблону сопоставления тега HTML не будет работать из-за «жадного» характера .*
:
>>> s = ‘<html><head><title>Title</title>’
>>> len(s)
32
>>> print re.match(‘<.*>’, s).span()
(0, 32)
>>> print re.match(‘<.*>’, s).group()
<html><head><title>Title</title>
РВ сопоставляет '<'
в первом теге — html, и .*
забирает остаток строки. В итоге сопоставление простирается от открывающей склюки '<'
тега html
до закрывающей скобки ‘>'
закрывающего тега /title
, что, конечно, не есть то, чего мы хотели.
В таком случае, решение заключается в использовании нежадных определителей *?, +?, ??
или {m,n}?
, которые сопоставляют так мало текста, как это возможно. В примере выше, будет выбран первый символ ‘>’ после ‘<‘, и только, если не получится, движок будет продолжать попытки найти символ ‘>’ на следующей позиции, в зависимости от того, как длинно имя тега. Это дает нужный результат:
>>> print re.match(‘<.*?>’, s).group()
<html>
(Заметим, что парсинг HTML или XML с использованием регулярных выражений является делом болезненным. Наспех сделанный шаблон может справиться с какими-то вещами, но рушится при изменении кода страницы. А хорошо продуманный шаблон может оказаться слишком сложным для того, чтобы пытаться его модифицировать. Для таких задач лучше использовать модули HTML или XML парсеров.)
Использование re.VERBOSE
К настоящему моменты вы, вероятно, заметили, что РВ обладают очень компактной записью, но иногда они не очень читабельны. РВ умеренной сложности могут представлять собой длинные последовательности слэшей, круглых скобок, метасимволов, что делает их трудными для чтения и понимания.
Для таких РВ может быть полезным указание флага VERBOSE при компиляции регулярного выражения потому что это позволяет форматировать регулярное выражение более ясным образом.
Флаг VERBOSE имеет несколько особенностей. Пробелы в РВ, которые не находятся внутри класса символов игнорируется. Это означает, что выражения, такие как dog | cat
эквивалентны менее читабельным беспробельным dog|cat
, но [a b] будет по-прежнему соответствовать символам 'a', 'b'
или пробелу. Кроме того, вы можете также помещать внутрь РВ комментарии, длящиеся с символа #
до следующей строки. Форматирование будет более аккуратным при использовании тройных кавычек:
pat = re.compile(r»»»
\s* # Skip leading whitespace
(?P<header>[^:]+) # Header name
\s* : # Whitespace, and a colon
(?P<value>.*?) # The header’s value — *? used to
# lose the following trailing whitespace
\s*$ # Trailing whitespace to end-of-line
«»», re.VERBOSE)
Это гораздо проще читается, чем:
pat = re.compile(r»\s*(?P<header>[^:]+)\s*:(?P<value>.*?)\s*$»)
В заключение
Документация модуля re
Хабраблог «Регулярные выражения»
Regexp editor
Регулярные выражения (regular expressions) — Блог программиста
Все мы используем поиск по строкам. Это касается не только программистов, но и любых бабушек, работающих с компьютером. При этом, одни люди страдают, а другие — используют регулярные выражения. Пара ситуаций для привлечения интереса:
- Вы пишете программу, в которой обрабатываются номера телефонов, допустим в формате +7(ххх)ххх-хх-хх. Возможно их надо найти в тексте, а может быть — проверить корректность. На месте номеров могли бы быть номер банковской карты, IP-адрес, электронная почта, ФИО (в формате Петров А.Ю.), да и вообще что угодно.
- В Microsoft Word при поиске и замене можно включить режим поддержки регулярных выражений поставив галочку напротив пункта «подстановочные знаки». Потом можно искать все то, что указано в первом пункте, но программу писать не требуется. И заменять можно. В LibreOffice/OpenOffice это тоже поддерживается.
- Естественно, регулярные выражения поддерживаются во всех современных средах разработки — Qt Creator, Microsoft Visual Studio, NetBeans, IntelliJ IDEA и даже блокнотах — Notepad++, kate, gedit и др. Вы пишете код и решили что-то переименовать, да как-то особенно…
Остается научиться всем этим пользоваться. Значительную часть описанных ниже примеров можно проверить в том же Notepad++ или Microsoft Word. Для других (связанных с программированием) — можно использовать сервис regex101, он удобен не только для обучения, но и для реальной разработки.
Содержание:
- Теоретический раздел
- Одиночные символы
- Квантификация
- Группировка (подвыражения)
- Что есть еще?
- Практический раздел. Ссылки
1 Теоретический раздел
Регулярные выражения представляют собой своеобразный язык описания строк. При этом, как и в любом языке, в нем есть определенные синтаксические конструкции и правила.
1.1 Одиночные символы
Символ «точка» (.) заменяет в регулярных выражениях любой символ. Так, например, если в тексте есть слова "порог"
и "пирог"
— то выражение "п.рог"
будет удовлетворять обоим из них. Ниже приведен пример такого поиска в тектовом редакторе kate, остальные примеры будут даваться без скриншотов.
Если же нас интересуют не все варианты замены символа — используется представление с квадратными скобками. В скобках перечисляются альтернативные символы. Также, в квадратных скобках можно задавать диапазоны символов с помощью «тире». Ниже приведена схема для выражения «var_[a-d][123]», можно попробовать выписать строки, которое оно описывает:
Если символ «тире» должен являться частью перечисления — его нужно ставить первым или последним. Например, в таком выражении:
ставить тире между "+"
и "*"
нельзя, так как это будет интерпретировано как диапазон.
Также с помощью перечислений можно искать «все символы кроме», для этого первым символом перечисления должен быть "^"
. Так, чтобы найти в тексте все символы кроме "ё"
, "й"
и символов "a-z"
можно использовать такое выражение: "[^ёйa-z]"
.
Если символ "^"
стоит вне квадратных скобок — то он задает начало строки (до сих пор поиск осуществлялся во всем тексте). Символ "$"
соответствует концу строки.
Если вдруг вам нужно найти в тексте какой-либо из «управляющих символов» — то его нужно экранировать с помощтю слеша. Так, например, символы "^"
, "["
в регулярном выражении должны быть заменены на "\^"
, "\["
. На практике часто приходится искать символ слеша, который также является управляющим и заменяется на "\\"
.
Наконец, для часто встречающихся категорий символов введены специальные обозначения:
Выражение | Символ |
---|---|
"\d" | цифра |
"\D" | все кроме цифры "[^0-9]" |
"\s" | пробельный символ (табуляции, пробелы) |
"\S" | все, кроме пробельных символов |
"\w" | буква (любой язык, в любом регистре) |
"\W" | все кроме букв |
"\b" | граница слова |
"\B" | не граница слова |
Такие обозначения могут использоваться в качестве элементов перечисления, например "[\d\w]"
соответствует букве или цифре.
1.2 Квантификация
Все, что написано выше не очень полезно без кванторов, с их помощью можно задавать количество повторений, стоящего слева от них символа. Все они приведены в таблице:
Выражение | Количество повторений |
---|---|
"*" | 0 или более раз |
"+" | 1 или более раз |
"?" | 0 или 1 раз |
"{n}" | точно n раз |
"{n,m}" | от n до m раз |
С помощью кванторов мы можем описать, например строку, содержащую номер банковской карты:
Под такое описание подойдут, например, строки "1234-1234-1234-1234"
и "12345678 12345678"
.
1.3 группировка (подвыражения)
Выражение может состоять из подвыражений, заключенных в круглые скобки. Для программиста это очень важно, так как к подвыражению можно обратиться по индексу. Кроме того, подвыражения используются для задания альтернатив, которые можно перечислять с помощью вертикальной черты. Так, например, следующее выражение соответствует строкам «+7 902», «8(902)» и еще множеству вариантов:
Тут "\("
используется для экранирования скобок. Подвыражения на практике применяются очень часто, но нам не всегда нужна возможность получить подстроку, соответствующую подвыражению. При выборе подстрок в коде вашей программы «лишние» подвыражения мешают, из-за них «съезжают» индексы, исправить ситуацию можно с использованием следующего синтаксиса: "(?:pattern)"
. Кроме того, такая форма записи более эффективна, т.к. сохраняет меньше данных.
Также, с группами связано так называемое «заглядывание вперед» — это нечасто применяемая на практике техника позволяет проверить соответствие подвыражению, не смещая позицию поиска и не запоминая найденное соответствие. Синтаксис используется следующий "(?=pattern)"
. Пусть дан следующий файл со списком языков программирования:
Basic структурный Lua процедурный Prolog логический С++ объектно-ориентированный Lisp функциональный Logo функциональный
По выражению
мы ожидаемо получим три строки, однако что если, к уже найденному подвыражению требуется применить какие-то дополнительные «фильтры»? То есть, после этой проверки мы хотим еще раз проверить названия языков. Сделать это можно заменив "?:"
на "?="
.
Теперь будут получены только две строки — Lua и Lisp, а второе подвыражение "(.*)"
будет сопоставлено с типами соответствующих языков.
Негативное заглядывания вперед ищет несоответствие строки шаблону "(?!pattern)"
. Такое выражение выбирает подстроки, не соответствующие "pattern"
без запоминания подстроки и не смещая текущую позицию поиска. Так, для рассмотренного выше примера, такой тип заглядывания вернет единственную строку с языком Logo. Первое подвыражение выберет строки с языками Basic, Prolog, С++ и Logo, а второе — оставит из них только те, чьи названия начинаются с символа "L"
.
1.4 Что есть еще?
Наряду с заглядыванием вперед, в некоторых реализациях поддерживается позитивное и негативное заглядывания назад — "(?<=шаблон)"
и "(?<!шаблон)"
, соответственно. Полезно знать, что нечто подобное существует, чтобы в случае чего — найти в справочнике и применить.
Описанное выше должно одинаково работать в любой среде, поддерживающей регулярные выражения, однако в отдельных реализациях доступно больше возможностей или синтаксис выражений может незначительно отличаться. С помощью регулярных выражений можно искать строки в тексте, однако в каком регистре выполняется поиск? — ответ зависит от реализации. Управлять регистром можно с помощью модификаторов : "(?i)"
включает чувствительность к регистру, а "(?-i)"
— выключает ее. Существуют и другие модификаторы, но они используются реже. Работа модификаторов зависит от реализации. Некоторые реализации поддерживают также флаги, которыми также можно управлять регистром.
Ряд реализаций поддерживает очень удобный поиск по условию: "(?(?=если)то|иначе)"
. Нечто подобное позволяет реализовать «просмотр вперед». «Если» условие выполнится — будет выполнено сопоставление с «то», в противном случае — с «иначе». Сопоставление в данном случае создает группу, к которой можно обратиться по индексу из вашего кода.
2 Практический раздел. Ссылки
Перед тем, как использовать регулярные выражения, стоит посмотреть в документацию по вашему языку программирования и используемой библиотеке, так как диалекты обладают особенностями. Например в Perl и некоторых версиях php можно описывать рекурсивные регулярные выражения, которые не поддерживаются большинством других реализаций; механизмом флагов отличается JavaScript и так далее. Незначительными отличиями могут обладать даже различные версии одной и той же библиотеки.
Отличаются регулярные выражения не только синтаксисом, но и реализацией. Регулярные выражения — это «не просто так». Строка, задающее выражение, преобразуется в автомат, от реализации которого зависит эффективность. Масштаб проблемы хорошо иллюстрирует график зависимости времени выполнения поиска от длины строки и реализации:
Картинка взята из статьи «Поиск с помощью регулярных выражений может быть простым и быстрым«. В ней можно прочитать про различные реализации выражений, а также о том, как написать выражение так, чтобы оно работало быстрее. Кстати, так как выражение преобразуется в автомат, то зачастую его удобно визуализировать — для этого есть специальные сервисы, например. Для последнего выражения статьи будет построен такой автомат:
Примеры использования регулярных выражений:
- для валидации вводимых в поля данных: QValidator примеры использования. Ряд библиотек построения графического пользовательского интерфейса позволяют закреплять к полям ввода валидаторы, которые не позволяет ввести в формы некорректные данные. По приведенной выше ссылке можно найти валидацию номера банковской карты и номера телефона с помощью регулярных выражений библиотеки Qt. Аналогичные механизмы есть в других языках, например в Java для этого используется пакет
javax.faces.validator.Validator
; - для парсинга сайтов: Парсер сайта на Qt, использование QRegExp. В примере с сайта-галереи выбираются и скачиваются картинки заданных категорий;
- для валидации данных, передаваемых в формате JSON ряд библиотек позволяет задавать схему. При этом для строковых полей могут быть заданы регулярные выражения. В качестве упражнения можно попробовать составить выражение для пароля — проверить что строка содержит символы в разном регистре и цифры.
В сообществе Программирование и алгоритмы можно посмотреть дополнительную литературу по теме. Книгу Гойвертса и Левитана рекомендую посмотреть особенно, так как в ней по-полочкам разобраны десятки примеров, причем с учетом специфики реализации регулярных выражений в конкретных языках программирования.
Регулярные выражения — Викиучебник
Регуля́рные выраже́ния (англ. regular expressions, жарг. регэ́кспы или ре́гексы) — система обработки текста, основанная на специальной системе записи образцов для поиска. Образец (англ. pattern), задающий правило поиска, по-русски также иногда называют «шаблоном», «маской».
Сейчас регулярные выражения используются многими текстовыми редакторами и утилитами для поиска и изменения текста на основе выбранных правил. Многие языки программирования уже поддерживают регулярные выражения для работы со строками. Например, Perl и Tcl имеют встроенный в их синтаксис механизм обработки регулярных выражений. Набор утилит (включая редактор sed и фильтр grep), поставляемых в дистрибутивах Unix, одним из первых способствовал популяризации понятия регулярных выражений.
Базовые понятия[править]
Регулярные выражения используются для сжатого описания некоторого множества строк с помощью шаблонов, без необходимости перечисления всех элементов этого множества. При составлении шаблонов используется специальный синтаксис, поддерживающий обычно следующие операции:
- Перечисление
- Вертикальная черта разделяет допустимые варианты. Например, «gray|grey» соответствует gray или grey.
- Группировка
- Круглые скобки используются для определения области действия и приоритета операторов. Например, «gray|grey» и «gr(a|e)y» являются разными образцами, но они оба описывают множество, содержащее gray и grey.
- Квантификация
- Квантификатор после символа или группы определяет, сколько раз предшествующее выражение может встречаться.
- {n,m}
- общее выражение, повторений может быть от n до m включительно.
- {n,}
- общее выражение, n и более повторений.
- {,m}
- общее выражение, не более m повторений.
- {n}
- общее выражение, ровно n повторений
- ?
- Знак вопроса означает 0 или 1 раз, то же самое, что и {0,1}. Например, «colou?r» соответствует и color, и colour.
- *
- Звёздочка означает 0, 1 или любое число раз ({0,}). Например, «go*gle» соответствует gogle, google, gooogle, ggle, и др.
- +
- Плюс означает хотя бы 1 раз ({1,}). Например, «go+gle» соответствует gogle, google и т. д. (но не ggle).
Конкретный синтаксис регулярных выражений зависит от реализации.
В теории формальных языков[править]
Регулярные выражения состоят из констант и операторов, которые определяют множества строк и множества операций на них соответственно. На данном конечном алфавите Σ определены следующие константы:
- (пустое множество) ∅ обозначает ∅
- (пустая строка) ε обозначает множество {ε}
- (строка) a в Σ обозначает множество {a}
и следующие операции:
- (связь, конкатенация) RS обозначает множество { αβ | α из R и β из S }. Пример: {«ab», «c»}{«d», «ef»} = {«abd», «abef», «cd», «cef»}.
- (перечисление) R|S обозначает объединение R и S.
- (замыкание Клини, звезда Клини) R* обозначает минимальное надмножество из R, которое содержит ε и закрыто связью строк. Это есть множество всех строк, которые могут быть получены связью нуля или более строк из R. Например, {«ab», «c»}* = {ε, «ab», «c», «abab», «abc», «cab», «cc», «ababab», … }.
Многие книги используют символы ∪, + или ∨ для перечисления вместо вертикальной черты.
Традиционные регулярные выражения в Unix[править]
Синтаксис «базовых» регулярных выражений Unix на данный момент определён POSIX как устаревший, но он до сих пор широко распространён из соображений обратной совместимости. Многие Unix-утилиты используют такие регулярные выражения по умолчанию.
В этом синтаксисе большинство символов соответствуют сами себе («a» соответствует «a» и т. д.). Исключения из этого правила называются метасимволами:
. | Соответствует любому единичному символу. |
[ ] | Соответствует любому единичному символу из числа заключённых в скобки. Символ «-» интерпретируется буквально только в том случае, если он расположен непосредственно после открывающей или перед закрывающей скобкой: [abc-] или [-abc]. В противном случае, он обозначает интервал символов. Например, [abc] соответствует «a», «b» или «c». [a-z] соответствует буквам нижнего регистра латинского алфавита. Эти обозначения могут и сочетаться: [abcq-z] соответствует a, b, c, q, r, s, t, u, v, w, x, y, z. Чтобы установить соответствие символам «[» или «]», достаточно, чтобы закрывающая скобка была первым символом после открывающей: [][ab] соответствует «]», «[», «a» или «b». |
[^ ] | Соответствует единичному символу из числа тех, которых нет в скобках. Например, [^abc] соответствует любому символу, кроме «a», «b» или «c». [^a-z] соответствует любому символу, кроме символов нижнего регистра в латинском алфавите. |
^ | Соответствует началу текста (или началу любой строки в мультистроковом режиме). Ищет с начала текста. |
$ | Соответствует концу текста (или концу любой строки в мультистроковом режиме). |
\(\) | Объявляет «отмеченное подвыражение» (иногда называется «захват»), которое может быть использовано позже (см. следующий элемент: \n). «Отмеченное подвыражение» также является «блоком». В отличие от других операторов, этот (в традиционном синтаксисе) требует бэкслеша. |
\n | Где n — это цифра от 1 до 9; соответствует n-му отмеченному подвыражению. Эта конструкция теоретически нерегулярна, она не была принята в расширенном синтаксисе регулярных выражений. |
* |
|
\{x,y\} | Соответствует последнему блоку, встречающемуся не менее x и не более y раз. Например, «a\{3,5\}» соответствует «aaa», «aaaa» или «aaaaa». В отличие от других операторов, этот (в традиционном синтаксисе) требует бэкслеша. |
Различные реализации регулярных выражений интерпретируют обратную косую черту перед метасимволами по-разному. Например, egrep и Perl интерпретируют скобки и вертикальную черту как метасимволы, если перед ними нет обратной косой черты и воспринимают их как обычные символы, если черта есть.
Многие диапазоны символов зависят от выбранных настроек локализации. POSIX стандартизовал объявление некоторых классов и категорий символов, как показано в следующей таблице:
POSIX класс | подобно | Perl | означает |
---|---|---|---|
[:upper:] | [A-Z] | символы верхнего регистра | |
[:lower:] | [a-z] | символы нижнего регистра | |
[:alpha:] | [A-Za-z] | символы верхнего и нижнего регистра | |
[:alnum:] | [A-Za-z0-9] | цифры, символы верхнего и нижнего регистра | |
[A-Za-z0-9_] | \w | цифры, символы верхнего, нижнего регистра и «_» | |
[^A-Za-z0-9_] | \W | не цифры, символы верхнего, нижнего регистра и «_» | |
[:digit:] | [0-9] | \d | цифры |
[^0-9] | \D | не цифры | |
[:xdigit:] | [0-9A-Fa-f] | шестнадцатеричные цифры | |
[:punct:] | [.,!?:…] | знаки пунктуации | |
[:blank:] | [ \t] | пробел и TAB | |
[:space:] | [ \t\n\r\f\v] | \s | символы пробелов(пропуска) |
[^ \t\n\r\f\v] | \S | не символы пробелов(пропуска) | |
[:cntrl:] | [\x00-\x1F\x7F] | символы управления | |
[:graph:] | [:alnum:] ∪ [:punct:] | символы печати | |
[:print:] | [\x20-\x7E] | символы печати и символы пропуска(видимые символы и пробелы) |
Защита метасимволов[править]
Cпособ представить сами метасимволы ., — [ ] и другие в регулярных выражениях без интерпретации, то есть, в качестве простых (не специальных) символов — предварить их обратной косой чертой: \. Например, чтобы представить сам символ «точка» (просто точка, и ничего более), надо написать \. (обратная косая черта, а за ней — точка). Чтобы представить символ открывающей квадратной скобки [, надо написать \[ (обратная косая черта и следом за ней скобка [) и т.д. Сам метасимвол \ тоже может быть защищен, то есть представлен как \\ (две обратных косых черты), и тогда интерпретатор регулярных выражений воспримет его как простой символ обратной косой черты \.
«Жадные» выражения[править]
Квантификаторам в регулярных выражениях соответствует максимально длинная строка из возможных (квантификаторы являются «жадными», англ. greedy). Это может оказаться значительной проблемой. Например, часто ожидают, что выражение (<.*>)
найдёт в тексте теги HTML. Однако этому выражению соответствует целиком строка
<p><b>Википедия</b> — свободная энциклопедия, в которой <i>каждый</i> может изменить или дополнить любую статью</p>
.
Эту проблему можно решить двумя способами. Первый состоит в том, что в регулярном выражении учитываются символы, не соответствующие желаемому образцу (<[^>]*>
для вышеописанного случая). Второй заключается в определении квантификатора как нежадного (ленивого, англ. lazy)— большинство реализаций позволяют это сделать, добавив после него знак вопроса.
Например, выражению (<.*?>)
соответствует не вся показанная выше строка, а отдельные теги (выделены цветом):
<p><b>Википедия</b> — свободная энциклопедия, в которой <i>каждый</i> может изменить или дополнить любую статью</p>
*?
— «не жадный» («ленивый») эквивалент*
+?
— «не жадный» («ленивый») эквивалент+
{n,}?
— «не жадный» («ленивый») эквивалент{n,}
Использование «ленивых» квантификаторов, правда, может повлечь за собой обратную проблему, когда выражению соответствует слишком короткая строка.
Также существуют квантификаторы повышения жадности, то, что захвачено ими однажды, назад уже не отдается.
Сверхжадные квантификаторы (possessive quantifiers)
*+
— «сверхжадный» эквивалент*
++
— «сверхжадный» эквивалент+
{n,}+
— «сверхжадный» эквивалент{n,}
Современные (расширенные) регулярные выражения в POSIX[править]
Регулярные выражения в POSIX аналогичны традиционному Unix-синтаксису, но с добавлением некоторых метасимволов:
+ | Указывает на то, что предыдущий символ или группа может повторяться один или несколько раз. В отличие от звёздочки, хотя бы одно повторение обязательно. |
? | Делает предыдущий символ или группу необязательной. Другими словами, в соответствующей строке она может отсутствовать, либо присутствовать ровно один раз. |
| | Разделяет альтернативные варианты регулярных выражений. Один символ задаёт две альтернативы, но их может быть и больше, достаточно использовать больше вертикальных чёрточек. Необходимо помнить, что этот оператор использует максимально возможную часть выражения. По этой причине, оператор альтернативы чаще всего используется внутри скобок. |
Также было отменено использование обратной косой черты: \{…\} становится {…} и \(…\) становится (…).
Perl-совместимые регулярные выражения (PCRE)[править]
Регулярные выражения в Perl имеют более богатый и в то же время предсказуемый синтаксис, чем даже в POSIX. По этой причине очень многие приложения используют именно Perl-совместимый синтаксис регулярных выражений.
Группы[править]
- ()
- Простая группа с захватом.
- (?:)
- Группа без захвата. То же самое, но заключённое в скобках выражение не добавляется к списку захваченных фрагментов. Например, если требуется найти или «здравствуйте», или «здраститя», но не важно, какое именно приветствие найдено, можно воспользоваться выражением
здра(?:ститя|вствуйте)
. - (?=)
- Группа с положительной опережающей проверкой (positive lookahead assertion). Продолжает поиск только если справа от текущей позиции в тексте находится заключённое в скобки выражение. При этом само выражение не захватывается. Например,
говор(?=ить)
найдёт «говор» в «говорить», но не в «говорит». Иными словами, ищет в строке «говор», после которого сразу идут символы «ить» — если находит, выдает истину, иначе — ложь (FALSE). - (?!)
- Группа с отрицательной опережающей проверкой (negative lookahead assertion). Продолжает поиск только если справа от текущей позиции в тексте не находится заключённое в скобки выражение. При этом само выражение не захватывается. Например,
говор(?!ить)
найдёт «говор» в «говорит», но не в «говорить». - (?<=)
- Группа с положительной ретроспективной проверкой (positive lookbehind assertion). Продолжает поиск только если слева от текущей позиции в тексте находится заключённое в скобки выражение. При этом само выражение не захватывается. Например,
(?<=об)говорить
найдёт «говорить» в «обговорить», но не в «уговорить». - (?<!)
- Группа с отрицательной ретроспективной проверкой (negative lookbehind assertion). Продолжает поиск только если слева от текущей позиции в тексте не находится заключённое в скобки выражение. При этом само выражение не захватывается. Например,
(?<!об)говорить
найдёт «говорить» в «уговорить», но не в «обговорить».
…
- NFA (Nondeterministic Finite State Machine; Недетерминированные Конечные Автоматы) используют «жадный» алгоритм отката, проверяя все возможные расширения регулярного выражения в определённом порядке и выбирая первое подходящее значение. NFA может обрабатывать подвыражения и обратные ссылки. Но из-за алгоритма отката традиционный NFA может проверять одно и то же место несколько раз, что отрицательно сказывается на скорости работы. Поскольку традиционный NFA принимает первое найденное соответствие, он может и не найти самое длинное из вхождений (этого требует стандарт POSIX, и существуют модификации NFA, выполняющие это требование — GNU sed). Именно такой механизм регулярных выражений используется, например, в Perl, Tcl и .NET.
- DFA (Deterministic Finite-state Automaton; Детерминированные Конечные Автоматы) работают линейно по времени, поскольку не используют откаты и никогда не проверяют какую-либо часть текста дважды. Они могут гарантированно найти самую длинную строку из возможных. DFA содержит только конечное состояние, следовательно, не обрабатывает обратных ссылок, а также не поддерживает конструкций с явным расширением, то есть, не способен обработать и подвыражения. DFA используется, например, в lex и egrep.
- Билл Смит Методы и алгоритмы вычислений на строках (regexp) = Computing Patterns in Strings. — М.: «Вильямс», 2006. — С. 496. — ISBN 0-201-39839-7
- Фридл Дж. Регулярные выражения. Библиотека программиста. — СПб.: Питер, 2001. 352 с. ISBN 5-318-00056-8.
- Бен Форта Освой самостоятельно регулярные выражения (regexp). PHP, Perl, JavaScript, Java, C#(си шарп), Visual Basic, ASP.NET,JSP, MySQL, Unix, Linux = Sams Teach Yourself Regular Expressions in 10 Minutes. — М.: «Вильямс», 2004. — С. 192. — ISBN 0-672-32566-7
- Царьков В. Б. Теория и методика построения регулярных выражений. Проблема самообразования. — 2010.
- Ян Гойвертс, Стивен Левитан Регулярные выражения. Сборник рецептов — СПб.: Символ-Плюс, 2010.352 с. ISBN 978-5-93286-181-3, ISBN 978-0-596-52068-7 (англ.)
6 пунктов, которые помогут легко разобраться с regexp
Давно хотели изучить regexp? Это небольшое руководство поможет разобраться с ними в 6 этапов, а обилие примеров позволит закрепить материал.
Regexp представляет собой группу символов или знаков, которая используется для поиска определенного текстового шаблона.
Регулярное выражение – это шаблон, который сравнивается с предметной строкой слева направо. Словосочетание “regular expression” применяется не так широко, вместо него обычно употребляют “regex” и “regexp”. Регулярное выражение используется для замены текста внутри строки, проверки формы, извлечения подстроки из строки на основе соответствия шаблона и т. д.
Предположим, вы создаете приложение и хотите определить правила, согласно которым пользователи будут выбирать себе имя. Например, мы хотим, чтобы оно содержало буквы, цифры, нижнее подчеркивание и дефисы. Также нам бы хотелось ограничить количество символов в имени пользователя, чтобы оно не выглядело уродливым. Поэтому для проверки будем использовать следующее регулярное выражение:
Это выражение принимает строки john_doe
, jo-hn_doe
и john12_as
. Однако имя пользователя Jo не будет соответствовать этому выражению, потому что оно содержит прописную букву, а также является слишком коротким.
Регулярное выражение — это всего лишь шаблон из символов, который мы используем для выполнения поиска в тексте. Например, регулярное выражение the
означает букву t
, за которой следует буква h
, за которой следует буква e
.
"the" => The fat cat sat on the mat.
Регулярное выражение 123
соответствует строке 123
. Регулярное выражение сопоставляется входной строке путем сравнения каждого символа в regexp с каждым символом входной строки. Регулярное выражение и входная строка сравниваются посимвольно. Обычно regex чувствительны к регистру, поэтому The
не соответствует строке the
.
"The" => The fat cat sat on the mat.
Тестировать выражение
Метасимволы служат строительными блоками regexp. Они не являются независимыми и обычно интерпретируются каким-либо образом. Некоторые метасимволы имеют особое значение, а потому помещаются в квадратные скобки. Метасимволы:
Метасимволы | Описание |
---|---|
. | Любой единичный символ, исключая новую строку. |
[ ] | Поиск набора символов, помещенных в скобки. |
[^ ] | Negated character class. Matches any character that is not contained between the square brackets |
* | 0 или больше повторений предшествующего символа. |
+ | 1 или больше повторений предшествующего символа. |
? | Делает предшествующий символ опциональным. |
{n,m} | Возвращает как минимум «n», но не более «m» повторений предшествующего символа. |
(xyz) | Находит группу символа в строго заданном порядке. |
| | Разделяет допустимые варианты. |
\ | Исключает следующий символ. Позволяет искать служебные символы [ ] ( ) { } . * + ? ^ $ \ | |
^ | Находит начало введенной строки. |
$ | Находит конец введенной строки. |
2.1 Точка
.
— это простейший пример метасимвола. Метасимвол .
соответствует любому единичному символу. Например, регулярное выражение .ar
означает: любой символ, за которым следует буква a
, за которой следует буква r
.
«.ar» => The car parked in the garage.
Тестировать выражение
2.2 Интервал символов
Интервал или набор символов также называют символьным классом. Для его обозначения используются квадратные скобки. Чтобы указать диапазон символов внутри класса, необходимо поставить знак тире. Порядок ряда символов в наборе неважен. Так, например, регулярное выражение [Tt]he
означает: T
или t
, за которым следует буква h
, за которой следует буква e
.
«[Tt]he » => The car parked in the garage.
Тестировать выражение
Стоит отметить, что точка, помещенная в квадратные скобки, означает именно точку, а ничто другое. Таким образом регулярное выражение ar[.]
означает строчный символ a
, за которым следует буква r
, за которой следует точка.
.
«ar [.]» => A garage is a good place to park a car.
Тестировать выражение
2.2.1 Отрицание набора символов
Обычно символ ^
представляет начало строки, но когда он внутри квадратных скобок, все символы, которые находятся после него, исключаются из шаблона. Например, выражение [^c]ar
поможет отыскать все символы кроме c
, за которыми следуют а
и r
.
"[^c]ar" => The car parked in the garage.
Тестировать выражение
2.3 Повторения
Следующие мета-символы +
,*
или ?
используются для того, чтобы обозначить допустимое количество повторения подшаблона. Их роль зависит от конкретного случая.
2.3.1 Звездочка
Этот символ поможет найти одно или более копий какого-либо символа. Регулярное выражение a*
означает 0 или более повторений символа a. Но если этот символ появится после набора или класса символов, тогда будут найдены повторения всего сета. Например, выражение [a-z]*
означает любое количество этих символов в строке.
"[a-z]*" => The car parked in the garage #21.
Тестировать выражение
Также символ может быть использован вместе с метасимволом .
для подбора строки из любых символов .*
.
Еще звездочку можно использовать со знаком пробела \s
, чтобы подобрать строку из пробелов. Например, выражение \s*cat\s
будет означать 0 или более пробелов, за которыми следует символ с
, за ним а
и t
, а за ними снова 0 либо больше пробелов.
"\s*cat\s*" => The fat cat sat on the concatenation.
Тестировать выражение
2.3.2 Плюс
+
соответствует одному или нескольким повторениям предыдущего символа. Например, регулярное выражение c.+t
означает: строчная буква c
, за которой следует хотя бы один символ, за которым следует строчный символ t
. Необходимо уточнить, что буква t
должна быть последней t в предложении.
"c.+t" => The fat cat sat on the mat.
Тестировать выражение
2.3.3. Вопросительный знак
В regexp метасимвол ?
делает предшествующий символ необязательным. Этот символ соответствует полному отсутствию или же одному экземпляру предыдущего символа. Например, регулярное выражение [T]?he
означает: необязательно заглавную букву T
, за которой следует строчный символ h
, за которым следует строчный символ e
."[T]he" => The car is parked in the garage.
Тестировать выражение
"[T]?he" => The car is parked in the garage.
Тестировать выражение
2.4 Скобки
Скобки в regexp, которые также называются квантификаторами, используются для указания допустимого количества повторов символа или группы символов. Например, регулярное выражение [0-9]{2,3}
означает, что допустимое количество цифр должно быть не менее двух цифр, но не более 3 (символы в диапазоне от 0 до 9).
"[0-9]{2,3}" => The number was 9.9997 but we rounded it off to 10.0.
Тестировать выражение
Мы можем убрать второе число. Например, выражение [0-9]{2,}
означает 2 или более цифр. Если мы также уберем запятую, то тогда выражение [0-9]{3}
будет находить только лишь 3 цифры, ни меньше и ни больше.
"[0-9]{2,}" => The number was 9.9997 but we rounded it off to 10.0.
Тестировать выражение
"[0-9]{3}" => The number was 9.9997 but rounded it off to 10.0.
Тестировать выражение
2.5 Символьная группа
Группа символов — это группа подшаблонов, которая записывается внутри скобок (...)
. Как было упомянуто раньше, если в регулярном выражении поместить квантификатор после символа, он повторит предыдущий символ. Но если мы поставим квантификатор после группы символов, он просто повторит всю группу. Например, регулярное выражение (ab)*
соответствует нулю или более повторениям символа «ab». Мы также можем использовать |
— метасимвол чередования внутри группы символов. Например, регулярное выражение (c|g|p)ar
означает: символ нижнего регистра c
, g
или p
, за которым следует символ a
, за которым следует символ r
.
"(c|g|p)ar" => The car is parked in the garage.
Тестировать выражение
2.6 Перечисление
В regexp вертикальная полоса |
используется для определения перечисления. Перечисление — это что-то вроде условия между несколькими выражениями. Можно подумать, что набор символов и перечисление работают одинаково, но это совсем не так, между ними существует огромная разница. Перечисление работает на уровне выражений, а набор символов на уровне знаков. Например, регулярное выражение (T|t)he|car
означает: T
или t
, сопровождаемая строчным символом h
, сопровождаемый строчным символом e
или строчным символом c
, а затем a
и r
.
"(T|t)he|car" => The car is parked in the garage.
Тестировать выражение
2.7 Исключение специального символа
Обратная косая черта \
используется в regexp, чтобы избежать символа, который следует за ней. Это позволяет нам указывать символ в качестве символа соответствия, включая зарезервированные { } [ ] / \ + * . $ ^ | ?
. Чтобы использовать специальный символ в качестве подходящего, перед ним нужно поставить \
.
Например, регулярное выражение .
используется для нахождения любого единичного символа. Регулярное выражение (f|c|m)at\.?
означает строчную букву f
, c
или m
, а затем a
, за ней t
с последующим дополнительным символом .
.
"(f|c|m)at\.?" => The fat cat sat on the mat.
Тестировать выражение
2.8 Анкеры — Привязки
В regexp мы используем привязки, чтобы проверить, является ли соответствующий символ первым или последним символом входной строки. Привязка бывает двух типов: первый — это ^
, который проверяет является ли соответствующий символ первым введенным, а второй — знак доллара, который проверяет, является ли соответствующий символ последним символом введенной строки.
2.8.1. Caret
Символ ^
используется в regexp, чтобы проверить, является ли соответствующий символ первым символом в введенной строке. Если мы применяем следующее регулярное выражение ^a
(проверяем является ли a первым символом) для введенной строки abc
, то оно будет равно a
. Но если мы применим регулярное выражение ^b
к той же строке, то оно ничего не вернет, потому что во входной строке abc
символ «b» не является первым. Давайте посмотрим на другое регулярное выражение ^(T|t)he
, которое означает: T
или t
— это символ начала входной строки, за которым следует строчный символ h
, а затем e
.
"(T|t)he" => The car is parked in the garage.
Тестировать выражение
"^(T|t)he" => The car is parked in the garage.
Тестировать выражение
2.8.2 Доллар
Знак доллара используется для проверки, является ли символ в выражении последним в введенной строке. Например (at\.)$
означает строчную а
, за которой следует t
, за которой следует a .
, которые должны заканчивать строку.
"(at\.)" => The fat cat. sat. on the mat.
Тестировать выражение
"(at\.)$" => The fat cat. sat. on the mat.
Тестировать выражение
Regexp позволяет использовать сокращения для некоторых наборов символов, что делает работу с ними более комфортной. Таким образом, здесь используются следующие сокращения:
Сокращение | Описание |
---|---|
. | Любой символ, кроме новой строки |
\w | Соответствует буквенно-цифровым символам:[a-zA-Z0-9_] |
\W | Соответствует не буквенно-цифровым символам:[^\w] |
\d | Соответствует цифрам: [0-9] |
\D | Соответсвует нецифровым знакам: [^\d] |
\s | Соответствует знаку пробела: [\t\n\f\r\p{Z}] |
\S | Соответствует символам без пробела: [^\s] |
Lookbehind и lookahead (также называемые lookaround) — это определенные типы non-capturing групп (Они используются для поиска, но сами в него не входят). Lookaheads используются, когда у нас есть условие, что этому шаблону предшествует или следует другой шаблон. Например, мы хотим получить все числа, которым предшествует символ $
из входной строки $4.44 and $10.88
. Мы будем использовать регулярное выражение (?<=\$)[0-9\.]*
, которое означает: получить все числа, содержащие .
и которым предшествует символ $
. Ниже приведены lookarounds, что используются в регулярных выражениях:
Символ | Описание |
---|---|
?= | Положительный Lookahead |
?! | Отрицательный Lookahead |
?<= | Положительный Lookbehind |
?<! | Отрицательный Lookbehind |
4.1 Положительный Lookahead
Положительный lookahead означает, что эта часть выражения должна следовать за впереди идущим выражением. Возвращаемое значение содержит текст, который совпадает с первой частью выражения. Чтобы определить позитивный lookahead, используют скобки. Внутри них размещают знак вопроса и знак равенства: (?=...)
. Само же выражение пишется после =
. Например, выражение (T|t)he(?=\sfat)
— это T
в верхнем или нижнем регистре, за которым следует h
и e
. В скобках мы определяем позитивный lookahead, который говорит движку регулярного выражения искать The
или the
, за которыми следует fat
.
"(T|t)he(?=\sfat)" => The fat cat sat on the mat.
Тестировать выражение
4.2 Отрицательный Lookahead
Негативный lookahead используется, когда нам нужно получить все совпадения в строке, за которой не следует определенный шаблон. Негативный lookahead определяется так же, как и позитивный, с той лишь разницей, что вместо знака равенства мы используем знак отрицания !
. Таким образом, наше выражение приобретает следующий вид: (?!...)
. Теперь рассмотрим (T|t)he(?!\sfat)
, что означает: получить все The
или the
в введенной строке, за которыми не следует слово fat
, предшествующее знаку пробела.
"(T|t)he(?!\sfat)" => The fat cat sat on the mat.
Тестировать выражение
4.3 Положительный Lookbehind
Положительный lookbehind используется для получения всех совпадений, которым предшествует определенный шаблон. Положительный lookbehind обозначается так: (?<=...)
. Например, регулярное выражение (?<=(T|t)he\s)(fat|mat)
означает получить все fat
или mat
из строки ввода, которые идут после слова The
или the
.
"(? The fat cat sat on the mat.
Тестировать выражение
4.4 Отрицательный Lookbehind
Отрицательный lookbehind используется для получения всех совпадений, которым не предшествует определенный шаблон. Отрицательный lookbehind обозначается выражением (?<!...)
. Например, регулярное выражение (?<!(T|t)he\s)(cat)
означает: получить все cat слова из строки ввода, которые не идут после The или the.
"(? The cat sat on cat.
Тестировать выражение
Флаги также часто называют модификаторами, так как они могут изменять вывод regexp. Флаги, приведенные ниже являются неотъемлемой частью и могут быть использованы в любом порядке или сочетании regexp.
Флаг | Описание |
---|---|
i | Нечувствительность к регистру: делает выражение нечувствительным к регистру. |
g | Глобальный поиск: поиск шаблона во всей строке ввода. |
m | Многострочность: анкер метасимвола работает в каждой строке. |
5.1 Нечувствительные к регистру
Модификатор i
используется для поиска совпадений, нечувствительных к регистру. Например, выражение /The/gi
означает прописную букву T
, за которой следуют h
и e
. И в самом конце выражения стоит i
, благодаря которому можно проигнорировать регистр. g
применяется для того, чтобы найти шаблон во всей введенной строке."The" => The fat cat sat on the mat.
Тестировать выражение
"/The/gi" => The fat cat sat on the mat.
Тестировать выражение
5.2 Глобальный поиск
Модификатор используется для выполнения глобального поиска шаблона(поиск будет продолжен после первого совпадения). Например, регулярное выражение /.(at)/g
означает любой символ, кроме новой строки, за которым следует строчный символ a
, а
затем t
. Поскольку мы использовали флаг g
в конце регулярного выражения, теперь он найдет все совпадения в вводимой строке, а не только в первой (что является стандартом).
"/.(at)/" => The fat cat sat on the mat.
Тестировать выражение
"/.(at)/g" => The fat cat sat on the mat.
Тестировать выражение
5.3 Многострочный поиск
Модификатор m
нужен для выполнения многострочного поиска. Как было сказано раннее, привязки (^, $)
используются для проверки, является ли шаблон началом или концом строки. Но если мы хотим, чтобы привязки работали в каждой строке, нужно использовать флаг m
. Например, регулярное выражение /at(.)?$/gm
означает: строчный символ a
, за которым следует t
и что угодно, только не новая строка. А благодаря флагу m
этот механизм регулярных выражений соответствует шаблону в конце каждой строки строки.
"/.at(.)?$/" => The fat
cat sat
on the mat.
Тестировать выражение
"/.at(.)?$/gm" => The fat
cat sat
on the mat.
Тестировать выражение
По умолчанию регулярные выражения выполняются благодаря «жадным» квантификаторам, им соответсвует максимально длинная строка из всех возможных.
"/(.*at)/" => The fat cat sat on the mat.
Тестировать выражение
Чтобы получить «ленивое» выражение, нужно использовать ?
. Так будет получена максимально короткая строка.
"/(.*?at)/" => The fat cat sat on the mat.
Тестировать выражение
Источник
Учебник по
Regex — \ b Границы слова
Метасимвол \ b является якорем, как и знак каретки и знак доллара. Он совпадает в позиции, которая называется «границей слова». Это совпадение нулевой длины.
Существует три различных позиции, которые квалифицируются как границы слова:
- Перед первым символом в строке, если первый символ является символом слова.
- После последнего символа в строке, если последний символ является символом слова.
- Между двумя символами в строке, где один символ слова, а другой не символ слова.
Проще говоря: \ b позволяет выполнять поиск «только слова целиком», используя регулярное выражение в форме \ bword \ b. «Символ слова» — это символ, который может использоваться для образования слов. Все символы, которые не являются «словесными символами», являются «несловесными символами».
Какие именно символы являются словесными, зависит от того, с каким регулярным выражением вы работаете.В большинстве разновидностей символы, которым соответствует класс сокращенных символов \ w, являются символами, которые рассматриваются как символы слова по границам слова. Java — исключение. Java поддерживает Unicode для \ b, но не для \ w.
Большинство разновидностей, за исключением описанных ниже, имеют только один метасимвол, который соответствует как перед словом, так и после слова. Это связано с тем, что любая позиция между символами никогда не может быть одновременно в начале и в конце слова. Использование только одного оператора упрощает вам задачу.
Поскольку цифры считаются символами слова, \ b4 \ b можно использовать для сопоставления 4, не являющейся частью большего числа. Это регулярное выражение не соответствует 44 листам формата А4. Таким образом, выражение «\ b соответствует до и после буквенно-цифровой последовательности» точнее, чем «до и после слова».
\ B — отрицательная версия \ b. \ B соответствует в каждой позиции, где \ b нет. Фактически, \ B соответствует любой позиции между двумя символами слова, а также любой позиции между двумя символами, не являющимися словами.
Заглянем внутрь механизма регулярных выражений
Давайте посмотрим, что произойдет, когда мы применим регулярное выражение \ bis \ b к строке. Этот остров прекрасен. Механизм запускается с первого токена \ b на первом символе T. Поскольку этот токен имеет нулевую длину, проверяется позиция перед символом. Здесь соответствует \ b, потому что T — это словесный символ, а символ перед ним — это пустота перед началом строки. Движок переходит к следующему токену: буквальному i. Механизм не переходит к следующему символу в строке, потому что предыдущий токен регулярного выражения был нулевой длины.i не соответствует T, поэтому движок повторяет первый токен в позиции следующего символа.
\ b не может совпадать в позиции между T и h. Он также не может совпадать между h и i, а также между i и s.
Следующий символ в строке — пробел. \ b соответствует здесь, потому что пробел не является символом слова, а предыдущий символ -. Опять же, двигатель продолжает с i, которое не совпадает с пробелом.
Перемещение символа и перезапуск с первым токеном регулярного выражения, \ b совпадает между пробелом и вторым i в строке.Далее механизм регулярных выражений обнаруживает, что i соответствует i, а s соответствует s. Теперь движок пытается сопоставить второй \ b в позиции перед l. Это не удается, потому что эта позиция находится между двумя символами слова. Движок возвращается к началу регулярного выражения и продвигает один символ к s на острове. Опять же, \ b не соответствует и продолжает соответствовать, пока не будет достигнут второй пробел. Он совпадает там, но сопоставление i не удается.
Но \ b соответствует позиции перед третьим i в строке.Двигатель продолжает работу и обнаруживает, что i соответствует i, а s соответствует s. Последний токен в регулярном выражении \ b также совпадает с позицией перед третьим пробелом в строке, потому что пробел не является символом слова, а символ перед ним.
Механизм успешно нашел слово в нашей строке, пропустив два предыдущих вхождения символов i и s. Если бы мы использовали регулярное выражение is, оно соответствовало бы is в This.
Границы слов Tcl
Границы слов, как описано выше, поддерживаются большинством разновидностей регулярных выражений.Заметными исключениями являются разновидности POSIX и XML Schema, которые вообще не поддерживают границы слов. Tcl использует другой синтаксис.
В Tcl \ b соответствует символу возврата, как и \ x08 в большинстве разновидностей регулярных выражений (включая Tcl). \ B соответствует одному символу обратной косой черты в Tcl, как и \\ во всех других разновидностях регулярных выражений (и в Tcl тоже).
Tcl использует букву «y» вместо буквы «b», чтобы соответствовать границам слова. \ y соответствует любой позиции границы слова, а \ Y соответствует любой позиции, которая не является границей слова.Эти токены регулярных выражений Tcl совпадают точно так же, как \ b и \ B в разновидностях регулярных выражений в стиле Perl. Они не делают различия между началом и концом слова.
Tcl имеет еще два маркера границы слова, которые различают начало и конец слова. \ m соответствует только началу слова. То есть, он соответствует любой позиции, слева от которой есть не-словесный символ, а справа — словесный символ. Он также соответствует началу строки, если первый символ в строке является символом слова.\ M соответствует только в конце слова. Он соответствует любой позиции, слева от которой есть символ слова, а справа — символ, не являющийся словом. Он также соответствует концу строки, если последний символ в строке является символом слова.
Единственным механизмом регулярных выражений, поддерживающим границы слов в стиле Tcl (помимо самого Tcl), является механизм JGsoft. В PowerGREP и EditPad Pro \ b и \ B — это границы слов в стиле Perl, а \ y, \ Y, \ m и \ M — границы слов в стиле Tcl.
В большинстве случаев отсутствие токенов \ m и \ M не является проблемой.\ yword \ y находит «только целые слова» вхождения слова «word» точно так же, как \ mword \ M. \ Mword \ m никогда не может найти нигде, так как \ M никогда не соответствует позиции, за которой следует символ слова, а \ m никогда не соответствует позиции, которой предшествует один. Если ваше регулярное выражение должно соответствовать символам до или после \ y, вы можете легко указать в регулярном выражении, должны ли эти символы быть словесными или несловесными. Если вы хотите сопоставить любое слово, \ y \ w + \ y даст тот же результат, что и \ m. + \ M. Использование \ w вместо точки автоматически ограничивает первый \ y началом слова, а второй \ y — концом слова.Обратите внимание, что \ y. + \ Y не будет работать. Это регулярное выражение соответствует каждому слову, а также каждой последовательности несловесных символов между словами в строке темы. Тем не менее, если ваш вариант поддерживает \ m и \ M, механизм регулярных выражений может применять \ m \ w + \ M немного быстрее, чем \ y \ w + \ y, в зависимости от его внутренней оптимизации.
Если ваш вариант регулярного выражения поддерживает просмотр вперед и назад, вы можете использовать (?
Если ваш вариант имеет опережающий взгляд, но не ретроспективный, а также имеет границы слов в стиле Perl, вы можете использовать \ b (? = \ W) для имитации \ m Tcl и \ b (?! \ W) для имитации \ M. \ b соответствует началу или концу слова, а функция просмотра вперед проверяет, является ли следующий символ частью слова или нет. Если да, то мы в начале слова. В противном случае мы оказываемся в конце слова.
Границы слов GNU
Расширения GNU для регулярных выражений POSIX добавляют поддержку границ слова \ b и \ B, как описано выше.GNU также использует собственный синтаксис для границ начала и конца слова. \ <соответствует началу слова, например \ m в Tcl. \> соответствует в конце слова, например \ M в Tcl.
Boost также рассматривает \ <и \> как границы слов при использовании грамматики ECMAScript, расширенной, egrep или awk.
Границы слов POSIX
Стандарт POSIX определяет [[: <:]] как границу начала слова и [[:>:]] как границу конца слова. Хотя синтаксис заимствован из скобочных выражений POSIX, эти токены представляют собой границы слов, которые не имеют ничего общего и не могут использоваться внутри классов символов.Tcl и GNU также поддерживают границы слов POSIX. PCRE поддерживает границы слов POSIX, начиная с версии 8.34. Boost поддерживает их во всех своих грамматиках.
Сделайте пожертвование
Этот веб-сайт только что сэкономил вам поездку в книжный магазин? Сделайте пожертвование в поддержку этого сайта, и вы получите пожизненного доступа без рекламы к этому сайту!
.
Краткий справочник по регулярным выражениям
Обновлено: 04.05.2019, Computer Hope
Регулярные выражения — это мощный инструмент для поиска и замены текста в программе или в командной строке. В этом документе описаны наиболее распространенные символы регулярных выражений и способы их использования.
Описание
Регулярные выражения (сокращенно «регулярное выражение») — это специальные строки, представляющие шаблон, который должен быть сопоставлен в операции поиска. Они являются важным инструментом во множестве вычислительных приложений, от языков программирования, таких как Java и Perl, до инструментов обработки текста, таких как grep, sed и текстовый редактор vim.»» означает, что « не соответствует строчной букве a».
В таблицах ниже описаны многие стандартные компоненты регулярных выражений.
Запись
Существуют разные так называемые «разновидности» регулярных выражений — например, Java, Perl и Python имеют несколько разные правила для регулярных выражений. На этой странице мы придерживаемся стандартного регулярного выражения, и вы сможете использовать этот справочник для любой реализации.
Якоря и границы
Якоря и границы позволяют описывать текст с точки зрения его местоположения.abc
Классы символов
При поиске текста полезно иметь возможность выбирать символы исключительно на основе их классификации.Основными классами символов являются «словесные» символы (например, числа и буквы) и «несловесные» символы (например, пробелы и знаки препинания).
Последовательность метасимволов | Значение | Пример выражения | Пример совпадения |
---|---|---|---|
. | Соответствует любому одиночному символу, кроме символа новой строки. | ab.def | abcdef , ab9def , ab = def |
\ с | Соответствует символу пробела (например, пробелу, табуляции, подаче формы и т. Д.) | abcd \ se | abcd e , abcd (вкладка) e |
\ S | НЕ пробел | \ S \ S \ s \ S | AB D , 99 (таб.) 9 |
\ w | Словесный символ. Символ слова — это буква, число или знак подчеркивания. Этот набор символов также может быть представлен набором символов регулярного выражения [a-zA-Z0-9_] | \ w \ {1, \} — \ w \ {1,} (см. Кванторы ниже) | добрые пожелания , надуманные |
\ Вт | НЕ словесный символ | \ w \ W \ {1, \} \ w | a,! — (? &; B , 9-5 |
Специальные пробельные символы
Кванторы
Квантификаторы позволяют объявлять количества данных как часть вашего шаблона.Например, вам может потребоваться сопоставить ровно шесть пробелов или найти каждую числовую строку длиной от четырех до восьми цифр.
Последовательность метасимволов | Значение | Пример выражения | Пример совпадения |
---|---|---|---|
* | Ноль или более предыдущего символа | ca * t | cat , ct , caaaaaaaaaaaat |
символ \ { m \} | Ровно м вхождений символа | f \ {3 \} | fff |
символ \ { m , n \} | Не менее м , но не более n вхождений символа | г \ {4,6 \} | гггг , гггг , ггггг |
символ \ { m , \} | Не менее м вхождений знаков | ч \ {2, \} | hh , hhhhhhhh и hhhhhhhhhhhhhh будут соответствовать, но h не будет |
Буквенные символы и последовательности
Метасимволы — мощный инструмент, потому что они имеют особое значение, но иногда их нужно сопоставить буквально.Например, вам может потребоваться поиск буквального знака доллара (« $ ») как часть прайс-листа или в компьютерной программе как часть имени переменной. Поскольку знак доллара — это метасимвол, который означает «конец строки» в регулярном выражении, вы должны экранировать его обратной косой чертой, чтобы использовать его буквально.
Последовательность метасимволов | Значение | Пример выражения | Пример совпадения |
---|---|---|---|
\ | Буквальная обратная косая черта | \ | \ |
\ ^ | Буквальная вставка | \ ^ \ {5 \} | ^^^^^ |
\ $ | Буквальный знак доллара | \ 5 | $ 5 |
\. | Буквальный период | Да \. | Да. |
\ * | Буквальная звездочка | опечатка \ * | опечатка * |
\ [ | Буквальный открытый кронштейн | [3 \ [] | 3 , [ |
\] | Буквальный закрывающий кронштейн | \] | ] |
Наборы символов и диапазоны
Набор символов — это явный список символов, которые могут соответствовать критериям поиска.Набор символов указывается заключением набора символов в скобки ( [ и ] ). Например, набор символов [abz] будет соответствовать любому из символов a , b или z , или их комбинации, такой как ab , za или baz .
Диапазоны — это тип набора символов, в котором между символами используется тире для обозначения всего диапазона символов между ними, а также самих начальных и конечных символов.Например, диапазон [e-h] будет соответствовать любому из символов e , f , g или h или любой их комбинации, например hef . Диапазон [3-5] будет соответствовать любой из цифр 3 , 4 или 5 или их комбинации, например 45 .
При определении диапазона символов вы можете выяснить точный порядок, в котором они появляются, просмотрев таблицу символов ASCII.
Последовательность метасимволов | Значение | Пример выражения | Пример совпадения |
---|---|---|---|
[ знаков ] | Символы, перечисленные в скобках, являются частью набора совпадающих символов | [abcd] | a , b , c , d , abcd |
[^ .abcd] | Любое появление любого символа, ЗА ИСКЛЮЧЕНИЕМ a , b , c , d . Например, , когда , zephyr , e , xyz | ||
[ символ — символ ] | Любой символ в диапазоне между двумя символами, включая символы, является частью набора | [а-я] | Любая строчная буква |
[^ символ ] | Любой символ, НЕ указанный в списке | [^ A] | Любой символ, ЗА ИСКЛЮЧЕНИЕМ заглавной буквы A |
Диапазоны также можно объединять путем конкатенации.Например: | [f-hAC-E3-5] | Соответствует любому появлению f , g , h , A , C , D , E , 3 , 4 , 5 | |
Диапазоны также можно изменять с помощью квантификатора. Например: | [a-c0-2] * | Соответствует нулю или нескольким последовательным вхождениям a , b , c , 0 , 1 , 2 .Например, ac1cb будет соответствовать |
Группировка
Группировка позволяет рассматривать другое выражение как единое целое.
Последовательность метасимволов | Значение | Пример выражения | Пример совпадения |
---|---|---|---|
\ ( выражение \) | выражение будет соответствовать группе | \ (ab \) | ab , ab racadabra |
Сгруппированные выражения можно рассматривать как единое целое, как и символ.Например: | \ (ab \) \ {3 \} | ababab cdefg |
Расширенные регулярные выражения
Расширенные регулярные выражения или ERE , являются расширением основных регулярных выражений.
ERE поддерживают дополнительные кванторы, не требуют экранирования определенных метасимволов и подчиняются другим специальным правилам. Если ваше приложение поддерживает расширенное регулярное выражение, обратитесь к руководству по их синтаксису.
grep — Инструмент командной строки для поиска текста, соответствующего регулярному выражению.
sed — Инструмент командной строки для фильтрации и преобразования текста с помощью регулярных выражений.
vim — Мощный текстовый редактор.
.
Язык регулярных выражений — Краткий справочник
- 10 минут на чтение
В этой статье
Регулярное выражение — это шаблон, которому обработчик регулярных выражений пытается сопоставить входной текст. Шаблон состоит из одного или нескольких символьных литералов, операторов или конструкций.Краткое введение см. В разделе Регулярные выражения .NET.
В каждом разделе этого краткого справочника перечислены определенные категории символов, операторов и конструкций, которые можно использовать для определения регулярных выражений.
Мы также предоставили эту информацию в двух форматах, которые вы можете скачать и распечатать для удобства:
Персонаж сбегает
Символ обратной косой черты (\) в регулярном выражении указывает, что следующий за ним символ либо является специальным символом (как показано в следующей таблице), либо его следует интерпретировать буквально.Для получения дополнительной информации см. Побеги персонажей.
Экранированный символ | Описание | Узор | Совпадения |
---|---|---|---|
\ а | Соответствует символу колокольчика, \ u0007. | \ а | "\ u0007" в "Ошибка!" + '\ u0007' |
\ б | В классе символов соответствует символу возврата \ u0008. | [\ b] {3,} | "\ b \ b \ b \ b" дюйм "\ b \ b \ b \ b" |
\ т | Соответствует табуляции, \ u0009. | (\ ш +) \ т | "item1 \ t" , "item2 \ t" в "item1 \ titem2 \ t" |
\ r | Соответствует возврату каретки, \ u000D. ( \ r не эквивалентно символу новой строки, \ n .) | \ г \ п (\ ш +) | "\ r \ nЭто" в "\ r \ nЭто \ nдве строки." |
\ v | Соответствует вертикальной табуляции, \ u000B. | [\ v] {2,} | "\ v \ v \ v" дюйм "\ v \ v \ v" |
\ f | Соответствует подаче страницы, \ u000C. | [\ f] {2,} | "\ f \ f \ f" дюйм "\ f \ f \ f" |
\ п | Соответствует новой строке, \ u000A. | \ г \ п (\ ш +) | "\ r \ nЭто" в "\ r \ nЭто \ nдве строки." |
\ e | Соответствует побегу, \ u001B. | \ e | "\ x001B" дюйм "\ x001B" |
\ nnn | Использует восьмеричное представление для указания символа ( nnn состоит из двух или трех цифр). | \ w \ 040 \ w | "a b" , "c d" in "a bc d" |
\ x nn | Использует шестнадцатеричное представление для указания символа ( nn состоит ровно из двух цифр). | \ w \ x20 \ w | "a b" , "c d" in "a bc d" |
\ c X | Соответствует управляющему символу ASCII, указанному как X или x , где X или x — это буква управляющего символа. | \ CC | "\ x0003" дюйм "\ x0003" (Ctrl-C) |
\ u nnnn | Соответствует символу Юникода с использованием шестнадцатеричного представления (ровно четыре цифры, как представлено nnnn ). | \ w \ u0020 \ w | "a b" , "c d" in "a bc d" |
\ | Если за ним следует символ, который не распознается как экранированный символ в этой и других таблицах этого раздела, соответствует этому символу. Например, \ * совпадает с \ x2A и \. совпадает с \ x2E . Это позволяет механизму регулярных выражений устранять неоднозначность языковых элементов (таких как * или?) И символьных литералов (представленных \ * или \? ). | \ d + [\ + - x \ *] \ d + | "2 + 2" и "3 * 9" дюйм "(2 + 2) * 3 * 9" |
Классы символов
Класс символов соответствует любому из набора символов. Классы символов включают языковые элементы, перечисленные в следующей таблице. Для получения дополнительной информации см. Классы символов.
Класс символов | Описание | Узор | Совпадения |
---|---|---|---|
[ группа_знаков ] | Соответствует любому одиночному символу в группе символов .aei] | "r" , "g" , "n" в "царствование" | |
[ первый - последний ] | Диапазон символов: соответствует любому одиночному символу в диапазоне от первых до последних . | [А-Я] | "A" , "B" дюйм "AB123" |
. | Подстановочный знак: соответствует любому одиночному символу, кроме \ n. Чтобы соответствовать буквальному символу точки (. Или | а.е. | «пр.» в «неф» |
\ p { название } | Соответствует любому одиночному символу в общей категории Unicode или именованному блоку, указанному в name . | \ p {Lu} | «C» , «L» в «City Lights» |
\ P { название } | Соответствует любому одиночному символу, который не входит в общую категорию Unicode или именованный блок, указанный в name . | \ P {Lu} | "i" , "t" , "y" in "City" |
\ w | Соответствует любому символу слова. | \ w | "I" , "D" , "A" , "1" , "3" дюйм "ID A1.3" |
\ Вт | Соответствует любому символу, не являющемуся словом. | \ Вт | "" , "." дюйм "ID A1.3" |
\ с | Соответствует любому символу пробела. | \ Вт \ с | "D" дюйм "ID A1.3" |
\ S | Соответствует любому символу, отличному от пробела. | \ с \ с | "_" in "int __ctr" |
\ d | Соответствует любой десятичной цифре. | \ г | "4" дюйм "4 = IV" |
\ D | Соответствует любому символу, кроме десятичной цифры. | \ D | "" , "=" , "" , "I" , "V" дюйм "4 = IV" |
Анкеры
Якоря, или атомарные утверждения нулевой ширины, приводят к успешному или неудачному совпадению в зависимости от текущей позиции в строке, но они не заставляют движок продвигаться по строке или потреблять символы.\ d {3}
"901"
в "901-333-"
$
\ n
в конце строки; в многострочном режиме это должно быть до конца строки или до \ n
в конце строки. - \ d {3}
$
"-333"
дюйм "-901-333"
\ A
\ A \ d {3}
"901"
в "901-333-"
\ Z
\ n
в конце строки. - \ d {3} \ Z
"-333"
дюйм "-901-333"
\ z
- \ d {3} \ z
"-333"
дюйм "-901-333"
\ G
\ G \ (\ d \)
»(1)«
, »(3)«
, »(5)«
дюйм »(1) (3) (5) [7] (9)«
\ б
\ w
(буквенно-цифровой) и \ W
(не буквенно-цифровым) символом. \ ч \ ш + \ с \ ш + \ б
"их тема"
, "их им"
в "их тема их"
\ B
\ b
. \ Изгиб \ ш * \ б
"заканчивается"
, "конец"
в "конец отправляет постоянный кредитор"
Группирующие конструкции
Группирующие конструкции очерчивают подвыражения регулярного выражения и обычно захватывают подстроки входной строки. Группирующие конструкции включают языковые элементы, перечисленные в следующей таблице. Для получения дополнительной информации см. Группирующие конструкции.
Группирующая конструкция | Описание | Узор | Совпадения |
---|---|---|---|
( подвыражение ) | Захватывает совпавшую часть выражения и присваивает ей порядковый номер, отсчитываемый от единицы. | (\ ш) \ 1 | "ее" дюйм "глубина" |
(? < имя > часть выражения ) или (? ' имя ' часть выражения ) | Захватывает совпадающее подвыражение в именованную группу. | (? <Двойной> \ w) \ k <двойной> | "ее" дюйм "глубина" |
(? < name1 - name2 > подвыражение ) или (? ' name1 - name2 ' подвыражение ) | Определяет определение балансирующей группы.((1-3) * (3-1)) « | ||
(?: часть выражения ) | Определяет группу без захвата. | Запись (?: Строка)? | "WriteLine" в "Console.WriteLine ()" |
(? Imnsx-imnsx: часть выражения ) | Применяет или отключает указанные параметры в подвыражении .Для получения дополнительной информации см. Параметры регулярного выражения. | A \ d {2} (? I: \ w +) \ b | "A12xl" , "A12XL" дюйм "A12xl A12XL a12xl" |
(? = подвыражение ) | Утверждение положительного просмотра вперед нулевой ширины. | \ ш + (? = \.) | "это" , "побежал" и "вышел" в "Он есть. Собака побежала. Солнце вышло." |
(?! часть выражения ) | Утверждение отрицательного просмотра вперед нулевой ширины. | \ b (?! Un) \ w + \ b | "уверен" , "использован" в "не уверен, что используется единство" |
(? <= часть выражения ) | Утверждение положительного просмотра назад нулевой ширины. | (? <= 19) \ d {2} \ b | "99" , "50" , "05" дюйм "1851 1999 1950 1905 2003" |
(? часть выражения | Утверждение отрицательного просмотра назад нулевой ширины. | (? | "51" , "03" дюйм "1851 1999 1950 1905 2003" |
(?> часть выражения ) | Атомная группа. | [13579] (?> A + B +) | "1ABB" , "3ABB" и "5AB" в "1ABB 3ABBC 5AB 5AC" |
Квантификаторы
Квантификатор указывает, сколько экземпляров предыдущего элемента (который может быть символом, группой или классом символов) должно присутствовать во входной строке, чтобы совпадение произошло.Квантификаторы включают языковые элементы, перечисленные в следующей таблице. Для получения дополнительной информации см. Квантификаторы.
Квантификатор | Описание | Узор | Совпадения |
---|---|---|---|
* | Соответствует предыдущему элементу ноль или более раз. | \ д * \. \ Д | ".0" , "19.9" , "219.9" |
+ | Один или несколько раз соответствует предыдущему элементу. | "be +" | "пчела" в "было" , "было" в "изогнуто" |
? | Соответствует предыдущему элементу ноль или один раз. | "рай? Н" | «пробежал» , «дождь» |
{ n } | Соответствует предыдущему элементу точно n раз. | ", \ d {3}" | ", 043" дюйм "1,043.6 " , ", 876 " , ", 543 " и ", 210 " дюйм " 9 876 543 210 " |
{ n ,} | Соответствует предыдущему элементу не менее n раз. | "\ d {2,}" | "166" , "29" , "1930" |
{ n , m } | Соответствует предыдущему элементу не менее n раз, но не более m раз. | "\ d {3,5}" | "166" , "17668" |
*? | Соответствует предыдущему элементу ноль или более раз, но как можно меньшее количество раз. | \ д *? \. \ Д | ".0" , "19.9" , "219.9" |
+? | Соответствует предыдущему элементу один или несколько раз, но как можно меньше раз. | "быть +?" | "быть" дюйм "было" , "быть" дюйм "изогнуто" |
?? | Соответствует предыдущему элементу ноль или один раз, но как можно меньше раз. | "рай ?? н" | «пробежал» , «дождь» |
{ n }? | Соответствует предыдущему элементу точно n раз. | ", \ d {3}?" | ", 043" дюйм "1043,6" , ", 876" , ", 543" и ", 210" дюйм "9 876 543 210" |
{ n ,}? | Соответствует предыдущему элементу как минимум n раз, но как можно меньше раз. | "\ d {2,}?" | "166" , "29" , "1930" |
{ n , m }? | Соответствует предыдущему элементу между n и m раза, но как можно меньше раз. | "\ d {3,5}?" | "166" , "17668" |
Конструкции обратных ссылок
Обратная ссылка позволяет идентифицировать ранее сопоставленное подвыражение в том же регулярном выражении. В следующей таблице перечислены конструкции обратной ссылки, поддерживаемые регулярными выражениями в .NET. Для получения дополнительной информации см. Конструкции обратных ссылок.
Конструкция обратной ссылки | Описание | Узор | Совпадения |
---|---|---|---|
\ номер | Обратная ссылка. Соответствует значению пронумерованной части выражения. | (\ ш) \ 1 | "ее" в "искать" |
\ k < название > | Именованная обратная ссылка. Соответствует значению именованного выражения. | (? | "ее" в "искать" |
Конструкции чередования
Конструкции с чередованием изменяют регулярное выражение, чтобы включить или / или сопоставление. Эти конструкции включают языковые элементы, перечисленные в следующей таблице. Для получения дополнительной информации см. Альтернативные конструкции.
Чередование конструкции | Описание | Узор | Совпадения |
---|---|---|---|
| | Соответствует любому элементу, разделенному вертикальной чертой ( | ). | -е (е | is | at) | " , " это " в " это день ". |
(? ( выражение ) да | нет ) | Соответствует да , если соответствует шаблон регулярного выражения, обозначенный выражением выражение ; в противном случае соответствует необязательной части № . Выражение интерпретируется как утверждение нулевой ширины. | (? (A) A \ d {2} \ b | \ b \ d {3} \ b) | "A10" , "910" дюйм "A10 C103 910" |
(? ( название ) да | нет ) | Соответствует да , если имя , именованная или пронумерованная группа захвата, имеет совпадение; в противном случае соответствует необязательному № . | (? <Кавычки> ")? (? (Цитируется).+? "| \ S + \ s) | "Dogs.jpg" , "\" Yiska plays.jpg \ "" in "Dogs.jpg \" Yiska plays.jpg \ "" |
Замены
Подстановки - это элементы языка регулярных выражений, которые поддерживаются в шаблонах замены. Для получения дополнительной информации см. Замены. Метасимволы, перечисленные в следующей таблице, являются атомарными утверждениями нулевой ширины.
Персонаж | Описание | Узор | Схема замены | Входная строка | Строка результата |
---|---|---|---|---|---|
$ номер | Заменяет подстроку, соответствующую номеру группы . | \ b (\ w +) (\ s) (\ w +) \ b | $ 3 $ 2 $ 1 | "один-два" | "два на один" |
$ { название } | Заменяет подстроку, соответствующую названной группе name . | \ b (? | $ {word2} $ {word1} | "один-два" | "два на один" |
$$ | Заменяет буквальный символ "$". | \ b (\ d +) \ s? | $$ 1 | "103 долл." | "103 доллара" |
$ и | Заменяет копию всего матча. | \ $? \ D * \.? \ D + | ** $ и ** | "1,30 $" | "** 1,30 доллара США **" |
$ ` | Заменяет весь текст входной строки перед совпадением. | В + | $ | "AABBCC" | "AAAACC" |
$ | Заменяет весь текст входной строки после совпадения. | В + | $ | "AABBCC" | "AACCCC" |
$ + | Заменяет последнюю захваченную группу. | В + (С +) | $ + | "AABBCCDD" | "AACCDD" |
$ _ | Заменяет всю входную строку. | В + | $ _ | "AABBCC" | «AAAABBCCCC» |
Параметры регулярных выражений
Можно указать параметры, управляющие тем, как обработчик регулярных выражений интерпретирует шаблон регулярного выражения. Многие из этих параметров могут быть указаны либо встроенными (в шаблоне регулярного выражения), либо как одна или несколько констант RegexOptions. В этом кратком справочнике перечислены только встроенные параметры.Дополнительные сведения о параметрах inline и RegexOptions см. В статье Параметры регулярного выражения.
Вы можете указать встроенный параметр двумя способами:
- При использовании разной конструкции
(? Imnsx-imnsx)
, где знак минус (-) перед параметром или набором параметров отключает эти параметры. Например,(? I-mn)
включает сопоставление без учета регистра (i
), выключает многострочный режим (m
) и отключает захват безымянных групп (n
).Параметр применяется к шаблону регулярного выражения с точки, в которой параметр определен, и действует либо до конца шаблона, либо до точки, где другая конструкция меняет параметр. - Используя конструкцию группирования
(? Imnsx-imnsx:
подвыражение)
, которая определяет параметры только для указанной группы.
Механизм регулярных выражений .NET поддерживает следующие встроенные параметры:
Опция | Описание | Узор | Совпадения |
---|---|---|---|
я | Использовать сопоставление без учета регистра. и $ соответствуют началу и концу строки, а не началу и концу строки. | Для примера см. Раздел «Многострочный режим» в параметрах регулярного выражения. | |
n | Не захватывать безымянные группы. | Для примера см. Раздел «Только явные захваты» в параметрах регулярного выражения. | |
с | Использовать однострочный режим. | Для примера см. Раздел «Однострочный режим» в параметрах регулярных выражений. | |
x | Игнорировать неэкранированные пробелы в шаблоне регулярного выражения. | \ b (? X) \ d + \ s \ w + | "1 трубкозуб" , "2 кошки" в "1 трубкозуб 2 кошки IV центурионы" |
Разные конструкции
Разные конструкции либо изменяют шаблон регулярного выражения, либо предоставляют информацию о нем. В следующей таблице перечислены различные конструкции, поддерживаемые.СЕТЬ. Для получения дополнительной информации см. Разные конструкции.
Конструкция | Определение | Пример |
---|---|---|
(? Imnsx-imnsx) | Устанавливает или отключает такие параметры, как нечувствительность к регистру в середине шаблона. Дополнительные сведения см. В разделе Параметры регулярного выражения. | \ bA (? I) b \ w + \ b соответствует "ABA" , "Able" в "ABA Able Act" |
(? # комментарий ) | Встроенный комментарий.Комментарий заканчивается первой закрывающей круглой скобкой. | \ bA (? # Соответствует словам, начинающимся с A) \ w + \ b |
# [до конца строки] | Комментарий в X-режиме. Комментарий начинается с неэкранированного номера # и продолжается до конца строки. | (? X) \ bA \ w + \ b # Соответствует словам, начинающимся с A |
См. Также
.
Регулярные выражения Краткое руководство
Это краткое руководство поможет быстро освоить регулярные выражения. Очевидно, что это краткое введение не может объяснить все, что нужно знать о регулярных выражениях. Для получения подробной информации обратитесь к руководству по регулярным выражениям. Каждая тема в кратком руководстве соответствует теме в учебнике, поэтому вы можете легко переключаться между ними.
Многие приложения и языки программирования имеют собственные реализации регулярных выражений, часто с небольшими, а иногда и со значительными отличиями от других реализаций.Когда два приложения используют разные реализации регулярных выражений, мы говорим, что они используют разные «разновидности регулярных выражений». В этом кратком руководстве объясняется синтаксис, поддерживаемый наиболее популярными разновидностями регулярных выражений.
Текстовые шаблоны и совпадения
Регулярное выражение, или, для краткости, регулярное выражение - это шаблон, описывающий определенный объем текста. На этом веб-сайте регулярные выражения выделены красным цветом как регулярные выражения. На самом деле это совершенно правильное регулярное выражение. Это самый простой шаблон, просто соответствующий регулярному выражению буквального текста.На этом сайте совпадения выделены синим цветом. Мы используем термин «строка» для обозначения текста, к которому применяется регулярное выражение. Строки выделены зеленым.
Символы со специальными значениями в регулярных выражениях выделяются разными цветами. Регулярное выражение (? X) ([Rr] egexp?) \? показывает мета-токены фиолетовым цветом, группы - зеленым, классы символов - оранжевым, кванторы и другие специальные токены - синим, а экранированные символы - серым.
Буквенные символы
Самое простое регулярное выражение состоит из одного буквального символа, такого как.Он соответствует первому появлению этого символа в строке. Если строка Jack is a boy, она соответствует a после J.
Это регулярное выражение также может соответствовать второму a. Это происходит только тогда, когда вы говорите механизму регулярных выражений начать поиск по строке после первого совпадения. В текстовом редакторе это можно сделать с помощью функции «Найти далее» или «Искать вперед». В языке программирования обычно есть отдельная функция, которую можно вызвать для продолжения поиска в строке после предыдущего совпадения., знак доллара $, точка или точка, вертикальная черта или вертикальная черта |, вопросительный знак?, звездочка или звездочка *, знак плюс +, открывающая скобка (, закрывающая скобка), открывающая квадратная скобка [, и открывающая фигурная скобка {. Эти специальные символы часто называют «метасимволами». Большинство из них являются ошибками при использовании в одиночку.
Если вы хотите использовать любой из этих символов в качестве литерала в регулярном выражении, вам нужно экранировать их обратной косой чертой. Если вы хотите сопоставить 1 + 1 = 2, правильное регулярное выражение - 1 \ + 1 = 2.В противном случае знак плюса имеет особое значение.
Дополнительные сведения о буквенных символах
Непечатаемые символы
Вы можете использовать специальные последовательности символов, чтобы вставить непечатаемые символы в регулярное выражение. Используйте \ t для соответствия символу табуляции (ASCII 0x09), \ r для возврата каретки (0x0D) и \ n для перевода строки (0x0A). Более экзотические непечатаемые элементы - это \ a (звонок, 0x07), \ e (escape, 0x1B), \ f (подача формы, 0x0C) и \ v (вертикальная табуляция, 0x0B). Помните, что текстовые файлы Windows используют \ r \ n для завершения строк, а текстовые файлы UNIX используют \ n.
Если ваше приложение поддерживает Unicode, используйте \ uFFFF или \ x {FFFF}, чтобы вставить символ Unicode. \ u20AC или \ x {20AC} соответствует знаку валюты евро.
Если ваше приложение не поддерживает Unicode, используйте \ xFF для сопоставления определенного символа по его шестнадцатеричному индексу в наборе символов. \ xA9 соответствует символу авторского права в наборе символов Latin-1.
Все непечатаемые символы могут использоваться непосредственно в регулярном выражении или как часть класса символов.
Дополнительные сведения о непечатаемых символах
Классы символов или наборы символов
«Класс символов» соответствует только одному из нескольких символов.Чтобы сопоставить a или e, используйте [ae]. Вы можете использовать это в gr [ae] y для соответствия серому или серому цвету. Класс символов соответствует только одному символу. gr [ae] y не соответствует серому, серому или тому подобному. Порядок символов внутри класса символов не имеет значения.
Вы можете использовать дефис внутри класса символов, чтобы указать диапазон символов. [0-9] соответствует одиночной цифре от 0 до 9. Вы можете использовать более одного диапазона. [0-9a-fA-F] соответствует одной шестнадцатеричной цифре без учета регистра.x] соответствует qu, о котором идет речь. не соответствует Ираку, поскольку после q нет символа, который бы соответствовал инвертированному классу символов.
Подробнее о классах символов
Классы сокращенных символов
\ d соответствует одиночному символу, который является цифрой, \ w соответствует «символу слова» (буквенно-цифровые символы плюс подчеркивание), а \ s соответствует пробельному символу (включая табуляцию и разрывы строк). Фактические символы, совпадающие с сокращениями, зависят от программного обеспечения, которое вы используете.В современных приложениях они включают в себя неанглийские буквы и цифры.
Дополнительные сведения о классах сокращенных символов
Точка соответствует (почти) любому символу
Точка соответствует одному символу, кроме символов разрыва строки. В большинстве приложений есть режим «точка соответствует всем» или «одна строка», в котором точка соответствует любому одиночному символу, включая разрывы строк.
gr.y соответствует серому, серому, gr% y и т. Д. Используйте точку с осторожностью. Часто класс символов или инвертированный класс символов быстрее и точнее.b соответствует только первому b в bob.
\ b соответствует границе слова. Граница слова - это позиция между символом, которому может соответствовать \ w, и символом, которому не может соответствовать \ w. \ b также соответствует началу и / или концу строки, если первый и / или последний символы в строке являются символами слова. \ B соответствует в каждой позиции, где \ b не может совпадать.
Дополнительные сведения о привязках
Чередование
Чередование - это регулярное выражение, эквивалентное «или».cat | dog соответствует cat в разделе О кошках и собаках. Если регулярное выражение применяется снова, оно соответствует собаке. Вы можете добавить столько альтернатив, сколько хотите: кошка | собака | мышь | рыба.
Чередование имеет самый низкий приоритет среди всех операторов регулярных выражений. cat | корм для собак соответствует корму для кошек или собак. Чтобы создать регулярное выражение, которое соответствует корму для кошек или корму для собак, вам необходимо сгруппировать альтернативы: (cat | dog) food.
Подробнее о чередовании
Повторение
Знак вопроса делает предыдущий токен в регулярном выражении необязательным.colou? r соответствует цвету или цвету.
Звездочка указывает механизму попытаться сопоставить предыдущий токен ноль или более раз. Плюс указывает движку попытаться сопоставить предыдущий токен один или несколько раз. <[A-Za-z] [A-Za-z0-9] *> соответствует тегу HTML без каких-либо атрибутов. <[A-Za-z0-9] +> легче писать, но он соответствует недопустимым тегам, таким как <1>.
Используйте фигурные скобки, чтобы указать определенное количество повторений. Используйте \ b [1-9] [0-9] {3} \ b для сопоставления числа от 1000 до 9999.\ b [1-9] [0-9] {2,4} \ b соответствует числу от 100 до 99999.
Подробнее о кванторах
Жадное и ленивое повторение
Операторы повторения или квантификаторы являются жадными. Они расширяют совпадение, насколько это возможно, и возвращают его только в том случае, если они должны удовлетворить оставшуюся часть регулярного выражения. Регулярное выражение <. +> Соответствует first в этом тесте first .
Поставьте вопросительный знак после квантификатора, чтобы сделать его ленивым. <.<>] +> для быстрого сопоставления тега HTML без учета атрибутов. Класс инвертированных символов более конкретен, чем точка, что помогает механизму регулярных выражений быстро находить совпадения.
Подробнее о жадных и ленивых квантификаторах
Группировка и захват
Поместите в круглые скобки несколько токенов, чтобы сгруппировать их. Затем вы можете применить к группе квантификатор. Например. Установить (значение)? соответствует Set или SetValue.
Круглые скобки создают группу захвата. В приведенном выше примере есть одна группа.После совпадения группа номер один ничего не содержит, если совпадение было выполнено. Он содержит значение, если было найдено значение SetValue. Как получить доступ к содержимому группы, зависит от программного обеспечения или языка программирования, который вы используете. Нулевая группа всегда содержит полное совпадение регулярного выражения.
Использовать специальный синтаксис Set (?: Value)? для группировки токенов без создания группы захвата. Это более эффективно, если вы не планируете использовать содержимое группы. Не путайте вопросительный знак в синтаксисе группы без захвата с квантификатором.
Подробнее о группировке и захвате
Обратные ссылки
В регулярном выражении вы можете использовать обратную ссылку \ 1, чтобы сопоставить тот же текст, который был сопоставлен группой захвата. ([abc]) = \ 1 соответствует a = a, b = b и c = c. Больше ни с чем не совпадает. Если ваше регулярное выражение имеет несколько групп захвата, они нумеруются, считая их открывающие скобки слева направо.
Подробнее о обратных ссылках
Именованные группы и обратные ссылки
Если в вашем регулярном выражении много групп, отслеживать их количество может быть затруднительно.Сделайте ваши регулярные выражения более удобными для чтения, назвав группы. (?
Подробнее об именованных группах
Свойства Unicode
\ p {L} соответствует одному символу из данной категории Unicode. L означает букву. \ P {L} соответствует одному символу, не входящему в данную категорию Unicode. Вы можете найти полный список категорий Unicode в руководстве.
Узнайте больше о регулярных выражениях Unicode
Lookaround
Lookaround - это особый вид группы. Токены внутри группы сопоставляются нормально, но затем механизм регулярных выражений заставляет группу отказаться от совпадения и сохраняет только результат. Lookaround соответствует позиции, как якоря. Он не расширяет совпадение регулярного выражения.
q (? = U) соответствует рассматриваемому q, но не в Ираке. Это позитивный взгляд на будущее. U не является частью общего совпадения регулярного выражения. Предварительный просмотр соответствует каждой позиции в строке перед u.
q (?! U) соответствует q в Ираке, но не подлежит сомнению. Это негативный взгляд вперед. Выполняется попытка использования маркеров внутри опережающего просмотра, их совпадение отбрасывается, а результат инвертируется.
Чтобы посмотреть назад, используйте просмотр назад. (? <= a) b соответствует b в abc. Это позитивный взгляд назад. (?
Внутри lookahead можно использовать полноценное регулярное выражение. Большинство приложений допускают только выражения фиксированной длины в ретроспективе.
Узнать больше о поиске
Синтаксис свободного пробела
Во многих приложениях есть опция, которая может быть помечена как «свободный интервал», «игнорировать пробелы» или «комментарии», что заставляет обработчик регулярных выражений игнорировать неэкранированные пробелы и разрывы строк и это заставляет символ # начинать комментарий, который длится до конца строки.Это позволяет вам использовать пробелы для форматирования вашего регулярного выражения таким образом, чтобы облегчить чтение людьми и, следовательно, упростить обслуживание.
Подробнее о свободных интервалах
Сделайте пожертвование
Этот веб-сайт только что сэкономил вам поездку в книжный магазин? Сделайте пожертвование в поддержку этого сайта, и вы получите неограниченного доступа к этому сайту без рекламы!
.