Регулярные выражения (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 ряд библиотек позволяет задавать схему. При этом для строковых полей могут быть заданы регулярные выражения. В качестве упражнения можно попробовать составить выражение для пароля — проверить что строка содержит символы в разном регистре и цифры.
В сообществе Программирование и алгоритмы можно посмотреть дополнительную литературу по теме. Книгу Гойвертса и Левитана рекомендую посмотреть особенно, так как в ней по-полочкам разобраны десятки примеров, причем с учетом специфики реализации регулярных выражений в конкретных языках программирования.
C++ — Регулярные выражения | c++ Tutorial
Вступление
Регулярные выражения (иногда называемые регулярными выражениями или регулярными выражениями ) представляют собой текстовый синтаксис, который представляет шаблоны, которые могут быть сопоставлены в используемых строках.
Регулярные выражения, введенные в c ++ 11 , могут опционально поддерживать возвращаемый массив совпадающих строк или другой текстовый синтаксис, определяющий, как заменить сопоставленные шаблоны в строках, на которых работает.
Синтаксис
- regex_match // Возвращает, была ли вся последовательность символов сопоставлена регулярным выражением, при желании, захват в объект соответствия
- regex_search // Возвращает, соответствует ли последовательность символов символу регулярным выражением, необязательно, захватывая объект соответствия
- regex_replace // Возвращает последовательность символов ввода, модифицированную регулярным выражением, с помощью строки замещающего формата
- regex_token_iterator // Инициализируется символьной последовательностью, определенной итераторами, списком индексов захвата для итерации и регулярным выражением. Dereferencing возвращает текущее индексированное соответствие регулярного выражения. Приращение шагов к следующему индексу захвата или, если он находится в последнем индексе, сбрасывает индекс и задерживает следующее вхождение регулярного выражения в последовательности символов
- regex_iterator // Инициализируется символьной последовательностью, определенной итераторами и регулярным выражением. Выделение возвращает часть последовательности символов, совпадающей со всем регулярным выражением. Приращение находит следующее вхождение регулярного выражения в последовательности символов
параметры
Подпись | Описание |
---|---|
bool regex_match(BidirectionalIterator first, BidirectionalIterator last, smatch& sm, const regex& re, regex_constraints::match_flag_type flags) | BidirectionalIterator — это любой итератор символов, который обеспечивает приращения и уменьшения операторов smatch может быть cmatch или любым другим другим вариантом match_results который принимает тип BidirectionalIterator аргумент smatch может быть пропущен, если результаты регулярного выражения не нужны. Возвращает, соответствует ли re полный символ последовательность, определенная first и last |
bool regex_match(const string& str, smatch& sm, const regex re&, regex_constraints::match_flag_type flags) | string может быть либо const char* либо string L-Value, функции, принимающие string R-значения, явно удалены. smatch может быть cmatch или любым другим другим вариантом match_results который принимает тип str аргумент smatch может быть опущен, если результаты регулярного выражения не нужны. Возвращает, соответствует ли re всей последовательности символов, определяемой str |
Регулярные выражения Связанные примеры
Шпаргалка по регулярным выражениям / Хабр
Доброго времени суток, друзья!
Представляю Вашему вниманию перевод статьи «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.
Благодарю за потраченное время. Надеюсь, оно было потрачено не зря.
регулярные выражения / Блог компании RUVDS.com / Хабр
Bash-скрипты: начало
Bash-скрипты, часть 2: циклы
Bash-скрипты, часть 3: параметры и ключи командной строки
Bash-скрипты, часть 4: ввод и вывод
Bash-скрипты, часть 5: сигналы, фоновые задачи, управление сценариями
Bash-скрипты, часть 6: функции и разработка библиотек
Bash-скрипты, часть 7: sed и обработка текстов
Bash-скрипты, часть 8: язык обработки данных awk
Bash-скрипты, часть 9: регулярные выражения
Bash-скрипты, часть 10: практические примеры
Bash-скрипты, часть 11: expect и автоматизация интерактивных утилит
Для того, чтобы полноценно обрабатывать тексты в bash-скриптах с помощью sed и awk, просто необходимо разобраться с регулярными выражениями. Реализации этого полезнейшего инструмента можно найти буквально повсюду, и хотя устроены все регулярные выражения схожим образом, основаны на одних и тех же идеях, в разных средах работа с ними имеет определённые особенности. Тут мы поговорим о регулярных выражениях, которые подходят для использования в сценариях командной строки Linux.
Этот материал задуман как введение в регулярные выражения, рассчитанное на тех, кто может совершенно не знать о том, что это такое. Поэтому начнём с самого начала.
Что такое регулярные выражения
У многих, когда они впервые видят регулярные выражения, сразу же возникает мысль, что перед ними бессмысленное нагромождение символов. Но это, конечно, далеко не так. Взгляните, например, на это регулярное выражение
^([a-zA-Z0-9_\-\.\+]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$
На наш взгляд даже абсолютный новичок сходу поймёт, как оно устроено и зачем нужно 🙂 Если же вам не вполне понятно — просто читайте дальше и всё встанет на свои места.
Регулярное выражение — это шаблон, пользуясь которым программы вроде sed или awk фильтруют тексты. В шаблонах используются обычные ASCII-символы, представляющие сами себя, и так называемые метасимволы, которые играют особую роль, например, позволяя ссылаться на некие группы символов.
Типы регулярных выражений
Реализации регулярных выражений в различных средах, например, в языках программирования вроде Java, Perl и Python, в инструментах Linux вроде sed, awk и grep, имеют определённые особенности. Эти особенности зависят от так называемых движков обработки регулярных выражений, которые занимаются интерпретацией шаблонов.
В Linux имеется два движка регулярных выражений:
- Движок, поддерживающий стандарт POSIX Basic Regular Expression (BRE).
- Движок, поддерживающий стандарт POSIX Extended Regular Expression (ERE).
Большинство утилит Linux соответствуют, как минимум, стандарту POSIX BRE, но некоторые утилиты (в их числе — sed) понимают лишь некое подмножество стандарта BRE. Одна из причин такого ограничения — стремление сделать такие утилиты как можно более быстрыми в деле обработки текстов.
Стандарт POSIX ERE часто реализуют в языках программирования. Он позволяет пользоваться большим количеством средств при разработке регулярных выражений. Например, это могут быть специальные последовательности символов для часто используемых шаблонов, вроде поиска в тексте отдельных слов или наборов цифр. Awk поддерживает стандарт ERE.
Существует много способов разработки регулярных выражений, зависящих и от мнения программиста, и от особенностей движка, под который их создают. Непросто писать универсальные регулярные выражения, которые сможет понять любой движок. Поэтому мы сосредоточимся на наиболее часто используемых регулярных выражениях и рассмотрим особенности их реализации для sed и awk.
Регулярные выражения POSIX BRE
Пожалуй, самый простой шаблон BRE представляет собой регулярное выражение для поиска точного вхождения последовательности символов в тексте. Вот как выглядит поиск строки в sed и awk:
$ echo "This is a test" | sed -n '/test/p'
$ echo "This is a test" | awk '/test/{print $0}'
Поиск текста по шаблону в sed
Поиск текста по шаблону в awk
Можно заметить, что поиск заданного шаблона выполняется без учёта точного места нахождения текста в строке. Кроме того, не имеет значение и количество вхождений. После того, как регулярное выражение найдёт заданный текст в любом месте строки, строка считается подходящей и передаётся для дальнейшей обработки.
Работая с регулярными выражениями нужно учитывать то, что они чувствительны к регистру символов:
$ echo "This is a test" | awk '/Test/{print $0}'
$ echo "This is a test" | awk '/test/{print $0}'
Регулярные выражения чувствительны к регистру
Первое регулярное выражение совпадений не нашло, так как слово «test», начинающееся с заглавной буквы, в тексте не встречается. Второе же, настроенное на поиск слова, написанного прописными буквами, обнаружило в потоке подходящую строку.
В регулярных выражениях можно использовать не только буквы, но и пробелы, и цифры:
$ echo "This is a test 2 again" | awk '/test 2/{print $0}'
Поиск фрагмента текста, содержащего пробелы и цифры
Пробелы воспринимаются движком регулярных выражений как обычные символы.
Специальные символы
При использовании различных символов в регулярных выражениях надо учитывать некоторые особенности. Так, существуют некоторые специальные символы, или метасимволы, использование которых в шаблоне требует особого подхода. Вот они:
.*[]^${}\+?|()
Если один из них нужен в шаблоне, его нужно будет экранировать с помощью обратной косой черты (обратного слэша) — \
.
Например, если в тексте нужно найти знак доллара, его надо включить в шаблон, предварив символом экранирования. Скажем, имеется файл myfile
с таким текстом:
There is 10$ on my pocket
Знак доллара можно обнаружить с помощью такого шаблона:
$ awk '/\$/{print $0}' myfile
Использование в шаблоне специального символа
Кроме того, обратная косая черта — это тоже специальный символ, поэтому, если нужно использовать его в шаблоне, его тоже надо будет экранировать. Выглядит это как два слэша, идущих друг за другом:
$ echo "\ is a special character" | awk '/\\/{print $0}'
Экранирование обратного слэша
Хотя прямой слэш и не входит в приведённый выше список специальных символов, попытка воспользоваться им в регулярном выражении, написанном для sed или awk, приведёт к ошибке:
$ echo "3 / 2" | awk '///{print $0}'
Неправильное использование прямого слэша в шаблоне
Если он нужен, его тоже надо экранировать:
$ echo "3 / 2" | awk '/\//{print $0}'
Экранирование прямого слэша
Якорные символы
Существуют два специальных символа для привязки шаблона к началу или к концу текстовой строки. Символ «крышка» — ^
позволяет описывать последовательности символов, которые находятся в начале текстовых строк. Если искомый шаблон окажется в другом месте строки, регулярное выражение на него не отреагирует. Выглядит использование этого символа так:
$ echo "welcome to likegeeks website" | awk '/^likegeeks/{print $0}'
$ echo "likegeeks website" | awk '/^likegeeks/{print $0}'
Поиск шаблона в начале строки
Символ ^
предназначен для поиска шаблона в начале строки, при этом регистр символов так же учитывается. Посмотрим, как это отразится на обработке текстового файла:
$ awk '/^this/{print $0}' myfile
Поиск шаблона в начале строки в тексте из файла
При использовании sed, если поместить крышку где-нибудь внутри шаблона, она будет восприниматься как любой другой обычный символ:
$ echo "This ^ is a test" | sed -n '/s ^/p'
Крышка, находящаяся не в начале шаблона в sed
В awk, при использовании такого же шаблона, данный символ надо экранировать:
$ echo "This ^ is a test" | awk '/s \^/{print $0}'
Крышка, находящаяся не в начале шаблона в awk
С поиском фрагментов текста, находящихся в начале строки мы разобрались. Что, если надо найти нечто, расположенное в конце строки?
В этом нам поможет знак доллара — $
, являющийся якорным символом конца строки:
$ echo "This is a test" | awk '/test$/{print $0}'
Поиск текста, находящегося в конце строки
В одном и том же шаблоне можно использовать оба якорных символа. Выполним обработку файла myfile
, содержимое которого показано на рисунке ниже, с помощью такого регулярного выражения:
$ awk '/^this is a test$/{print $0}' myfile
Шаблон, в котором использованы специальные символы начала и конца строки
Как видно, шаблон среагировал лишь на строку, полностью соответствующую заданной последовательности символов и их расположению.
Вот как, пользуясь якорными символами, отфильтровать пустые строки:
$ awk '!/^$/{print $0}' myfile
В данном шаблоне использовал символ отрицания, восклицательный знак — !
. Благодаря использованию такого шаблона выполняется поиск строк, не содержащих ничего между началом и концом строки, а благодаря восклицательному знаку на печать выводятся лишь строки, которые не соответствуют этому шаблону.
Символ «точка»
Точка используется для поиска любого одиночного символа, за исключением символа перевода строки. Передадим такому регулярному выражению файл myfile
, содержимое которого приведено ниже:
$ awk '/.st/{print $0}' myfile
Использование точки в регулярных выражениях
Как видно по выведенным данным, шаблону соответствуют лишь первые две строки из файла, так как они содержат последовательность символов «st», предварённую ещё одним символом, в то время как третья строка подходящей последовательности не содержит, а в четвёртой она есть, но находится в самом начале строки.
Классы символов
Точка соответствует любому одиночному символу, но что если нужно более гибко ограничить набор искомых символов? В подобной ситуации можно воспользоваться классами символов.
Благодаря такому подходу можно организовать поиск любого символа из заданного набора. Для описания класса символов используются квадратные скобки — []
:
$ awk '/[oi]th/{print $0}' myfile
Описание класса символов в регулярном выражении
Тут мы ищем последовательность символов «th», перед которой есть символ «o» или символ «i».
Классы оказываются очень кстати, если выполняется поиск слов, которые могут начинаться как с прописной, так и со строчной буквы:
$ echo "this is a test" | awk '/[Tt]his is a test/{print $0}'
$ echo "This is a test" | awk '/[Tt]his is a test/{print $0}'
Поиск слов, которые могут начинаться со строчной или прописной буквы
Классы символов не ограничены буквами. Тут можно использовать и другие символы. Нельзя заранее сказать, в какой ситуации понадобятся классы — всё зависит от решаемой задачи.
Отрицание классов символов
Классы символов можно использовать и для решения задачи, обратной описанной выше. А именно, вместо поиска символов, входящих в класс, можно организовать поиск всего, что в класс не входит. Для того, чтобы добиться такого поведения регулярного выражения, перед списком символов класса нужно поместить знак ^
. Выглядит это так:
$ awk '/[^oi]th/{print $0}' myfile
Поиск символов, не входящих в класс
В данном случае будут найдены последовательности символов «th», перед которыми нет ни «o», ни «i».
Диапазоны символов
В символьных классах можно описывать диапазоны символов, используя тире:
$ awk '/[e-p]st/{print $0}' myfile
Описание диапазона символов в символьном классе
В данном примере регулярное выражение реагирует на последовательность символов «st», перед которой находится любой символ, расположенный, в алфавитном порядке, между символами «e» и «p».
Диапазоны можно создавать и из чисел:
$ echo "123" | awk '/[0-9][0-9][0-9]/'
$ echo "12a" | awk '/[0-9][0-9][0-9]/'
Регулярное выражение для поиска трёх любых чисел
В класс символов могут входить несколько диапазонов:
$ awk '/[a-fm-z]st/{print $0}' myfile
Класс символов, состоящий из нескольких диапазонов
Данное регулярное выражение найдёт все последовательности «st», перед которыми есть символы из диапазонов a-f
и m-z
.
Специальные классы символов
В BRE имеются специальные классы символов, которые можно использовать при написании регулярных выражений:
[[:alpha:]]
— соответствует любому алфавитному символу, записанному в верхнем или нижнем регистре.[[:alnum:]]
— соответствует любому алфавитно-цифровому символу, а именно — символам в диапазонах0-9
,A-Z
,a-z
.[[:blank:]]
— соответствует пробелу и знаку табуляции.[[:digit:]]
— любой цифровой символ от0
до9
.[[:upper:]]
— алфавитные символы в верхнем регистре —A-Z
.[[:lower:]]
— алфавитные символы в нижнем регистре —a-z
.[[:print:]]
— соответствует любому печатаемому символу.[[:punct:]]
— соответствует знакам препинания.[[:space:]]
— пробельные символы, в частности — пробел, знак табуляции, символыNL
,FF
,VT
,CR
.
Использовать специальные классы в шаблонах можно так:
$ echo "abc" | awk '/[[:alpha:]]/{print $0}'
$ echo "abc" | awk '/[[:digit:]]/{print $0}'
$ echo "abc123" | awk '/[[:digit:]]/{print $0}'
Специальные классы символов в регулярных выражениях
Символ «звёздочка»
Если в шаблоне после символа поместить звёздочку, это будет означать, что регулярное выражение сработает, если символ появляется в строке любое количество раз — включая и ситуацию, когда символ в строке отсутствует.
$ echo "test" | awk '/tes*t/{print $0}'
$ echo "tessst" | awk '/tes*t/{print $0}'
Использование символа * в регулярных выражениях
Этот шаблонный символ обычно используют для работы со словами, в которых постоянно встречаются опечатки, или для слов, допускающих разные варианты корректного написания:
$ echo "I like green color" | awk '/colou*r/{print $0}'
$ echo "I like green colour " | awk '/colou*r/{print $0}'
Поиск слова, имеющего разные варианты написания
В этом примере одно и то же регулярное выражение реагирует и на слово «color», и на слово «colour». Это так благодаря тому, что символ «u», после которого стоит звёздочка, может либо отсутствовать, либо встречаться несколько раз подряд.
Ещё одна полезная возможность, вытекающая из особенностей символа звёздочки, заключается в комбинировании его с точкой. Такая комбинация позволяет регулярному выражению реагировать на любое количество любых символов:
$ awk '/this.*test/{print $0}' myfile
Шаблон, реагирующий на любое количество любых символов
В данном случае неважно сколько и каких символов находится между словами «this» и «test».
Звёздочку можно использовать и с классами символов:
$ echo "st" | awk '/s[ae]*t/{print $0}'
$ echo "sat" | awk '/s[ae]*t/{print $0}'
$ echo "set" | awk '/s[ae]*t/{print $0}'
Использование звёздочки с классами символов
Во всех трёх примерах регулярное выражение срабатывает, так как звёздочка после класса символов означает, что если будет найдено любое количество символов «a» или «e», а также если их найти не удастся, строка будет соответствовать заданному шаблону.
Регулярные выражения POSIX ERE
Шаблоны стандарта POSIX ERE, которые поддерживают некоторые утилиты Linux, могут содержать дополнительные символы. Как уже было сказано, awk поддерживает этот стандарт, а вот sed — нет.
Тут мы рассмотрим наиболее часто используемые в ERE-шаблонах символы, которые пригодятся вам при создании собственных регулярных выражений.
▍Вопросительный знак
Вопросительный знак указывает на то, что предшествующий символ может встретиться в тексте один раз или не встретиться вовсе. Этот символ — один из метасимволов повторений. Вот несколько примеров:
$ echo "tet" | awk '/tes?t/{print $0}'
$ echo "test" | awk '/tes?t/{print $0}'
$ echo "tesst" | awk '/tes?t/{print $0}'
Вопросительный знак в регулярных выражениях
Как видно, в третьем случае буква «s» встречается дважды, поэтому на слово «tesst» регулярное выражение не реагирует.
Вопросительный знак можно использовать и с классами символов:
$ echo "tst" | awk '/t[ae]?st/{print $0}'
$ echo "test" | awk '/t[ae]?st/{print $0}'
$ echo "tast" | awk '/t[ae]?st/{print $0}'
$ echo "taest" | awk '/t[ae]?st/{print $0}'
$ echo "teest" | awk '/t[ae]?st/{print $0}'
Вопросительный знак и классы символов
Если символов из класса в строке нет, или один из них встречается один раз, регулярное выражение срабатывает, однако стоит в слове появиться двум символам и система уже не находит в тексте соответствия шаблону.
▍Символ «плюс»
Символ «плюс» в шаблоне указывает на то, что регулярное выражение обнаружит искомое в том случае, если предшествующий символ встретится в тексте один или более раз. При этом на отсутствие символа такая конструкция реагировать не будет:
$ echo "test" | awk '/te+st/{print $0}'
$ echo "teest" | awk '/te+st/{print $0}'
$ echo "tst" | awk '/te+st/{print $0}'
Символ «плюс» в регулярных выражениях
В данном примере, если символа «e» в слове нет, движок регулярных выражений не найдёт в тексте соответствий шаблону. Символ «плюс» работает и с классами символов — этим он похож на звёздочку и вопросительный знак:
$ echo "tst" | awk '/t[ae]+st/{print $0}'
$ echo "test" | awk '/t[ae]+st/{print $0}'
$ echo "teast" | awk '/t[ae]+st/{print $0}'
$ echo "teeast" | awk '/t[ae]+st/{print $0}'
Знак «плюс» и классы символов
В данном случае если в строке имеется любой символ из класса, текст будет сочтён соответствующим шаблону.
▍Фигурные скобки
Фигурные скобки, которыми можно пользоваться в ERE-шаблонах, похожи на символы, рассмотренные выше, но они позволяют точнее задавать необходимое число вхождений предшествующего им символа. Указывать ограничение можно в двух форматах:
n —
число, задающее точное число искомых вхожденийn, m —
два числа, которые трактуются так: «как минимум n раз, но не больше чем m».
Вот примеры первого варианта:
$ echo "tst" | awk '/te{1}st/{print $0}'
$ echo "test" | awk '/te{1}st/{print $0}'
Фигурные скобки в шаблонах, поиск точного числа вхождений
В старых версиях awk нужно было использовать ключ командной строки --re-interval
для того, чтобы программа распознавала интервалы в регулярных выражениях, но в новых версиях этого делать не нужно.
$ echo "tst" | awk '/te{1,2}st/{print $0}'
$ echo "test" | awk '/te{1,2}st/{print $0}'
$ echo "teest" | awk '/te{1,2}st/{print $0}'
$ echo "teeest" | awk '/te{1,2}st/{print $0}'
Интервал, заданный в фигурных скобках
В данном примере символ «e» должен встретиться в строке 1 или 2 раза, тогда регулярное выражение отреагирует на текст.
Фигурные скобки можно применять и с классами символов. Тут действуют уже знакомые вам принципы:
$ echo "tst" | awk '/t[ae]{1,2}st/{print $0}'
$ echo "test" | awk '/t[ae]{1,2}st/{print $0}'
$ echo "teest" | awk '/t[ae]{1,2}st/{print $0}'
$ echo "teeast" | awk '/t[ae]{1,2}st/{print $0}'
Фигурные скобки и классы символов
Шаблон отреагирует на текст в том случае, если в нём один или два раза встретится символ «a» или символ «e».
▍Символ логического «или»
Символ |
— вертикальная черта, означает в регулярных выражениях логическое «или». Обрабатывая регулярное выражение, содержащее несколько фрагментов, разделённых таким знаком, движок сочтёт анализируемый текст подходящим в том случае, если он будет соответствовать любому из фрагментов. Вот пример:
$ echo "This is a test" | awk '/test|exam/{print $0}'
$ echo "This is an exam" | awk '/test|exam/{print $0}'
$ echo "This is something else" | awk '/test|exam/{print $0}'
Логическое «или» в регулярных выражениях
В данном примере регулярное выражение настроено на поиск в тексте слов «test» или «exam». Обратите внимание на то, что между фрагментами шаблона и разделяющим их символом |
не должно быть пробелов.
Группировка фрагментов регулярных выражений
Фрагменты регулярных выражений можно группировать, пользуясь круглыми скобками. Если сгруппировать некую последовательность символов, она будет восприниматься системой как обычный символ. То есть, например, к ней можно будет применить метасимволы повторений. Вот как это выглядит:
$ echo "Like" | awk '/Like(Geeks)?/{print $0}'
$ echo "LikeGeeks" | awk '/Like(Geeks)?/{print $0}'
Группировка фрагментов регулярных выражений
В данных примерах слово «Geeks» заключено в круглые скобки, после этой конструкции идёт знак вопроса. Напомним, что вопросительный знак означает «0 или 1 повторение», в результате регулярное выражение отреагирует и на строку «Like», и на строку «LikeGeeks».
Практические примеры
После того, как мы разобрали основы регулярных выражений, пришло время сделать с их помощью что-нибудь полезное.
▍Подсчёт количества файлов
Напишем bash-скрипт, который подсчитывает файлы, находящиеся в директориях, которые записаны в переменную окружения PATH
. Для того, чтобы это сделать, понадобится, для начала, сформировать список путей к директориям. Сделаем это с помощью sed, заменив двоеточия на пробелы:
$ echo $PATH | sed 's/:/ /g'
Команда замены поддерживает регулярные выражения в качестве шаблонов для поиска текста. В данном случае всё предельно просто, ищем мы символ двоеточия, но никто не мешает использовать здесь и что-нибудь другое — всё зависит от конкретной задачи.
Теперь надо пройтись по полученному списку в цикле и выполнить там необходимые для подсчёта количества файлов действия. Общая схема скрипта будет такой:
mypath=$(echo $PATH | sed 's/:/ /g')
for directory in $mypath
do
done
Теперь напишем полный текст скрипта, воспользовавшись командой ls
для получения сведений о количестве файлов в каждой из директорий:
#!/bin/bash
mypath=$(echo $PATH | sed 's/:/ /g')
count=0
for directory in $mypath
do
check=$(ls $directory)
for item in $check
do
count=$[ $count + 1 ]
done
echo "$directory - $count"
count=0
done
При запуске скрипта может оказаться, что некоторых директорий из PATH
не существует, однако, это не помешает ему посчитать файлы в существующих директориях.
Подсчёт файлов
Главная ценность этого примера заключается в том, что пользуясь тем же подходом, можно решать и куда более сложные задачи. Какие именно — зависит от ваших потребностей.
▍Проверка адресов электронной почты
Существуют веб-сайты с огромными коллекциями регулярных выражений, которые позволяют проверять адреса электронной почты, телефонные номера, и так далее. Однако, одно дело — взять готовое, и совсем другое — создать что-то самому. Поэтому напишем регулярное выражение для проверки адресов электронной почты. Начнём с анализа исходных данных. Вот, например, некий адрес:
[email protected]
Имя пользователя, username
, может состоять из алфавитно-цифровых и некоторых других символов. А именно, это точка, тире, символ подчёркивания, знак «плюс». За именем пользователя следует знак @.
Вооружившись этими знаниями, начнём сборку регулярного выражения с его левой части, которая служит для проверки имени пользователя. Вот что у нас получилось:
^([a-zA-Z0-9_\-\.\+]+)@
Это регулярное выражение можно прочитать так: «В начале строки должен быть как минимум один символ из тех, которые имеются в группе, заданной в квадратных скобках, а после этого должен идти знак @».
Теперь — очередь имени хоста — hostname
. Тут применимы те же правила, что и для имени пользователя, поэтому шаблон для него будет выглядеть так:
([a-zA-Z0-9_\-\.]+)
Имя домена верхнего уровня подчиняется особым правилам. Тут могут быть лишь алфавитные символы, которых должно быть не меньше двух (например, такие домены обычно содержат код страны), и не больше пяти. Всё это значит, что шаблон для проверки последней части адреса будет таким:
\.([a-zA-Z]{2,5})$
Прочесть его можно так: «Сначала должна быть точка, потом — от 2 до 5 алфавитных символов, а после этого строка заканчивается».
Подготовив шаблоны для отдельных частей регулярного выражения, соберём их вместе:
^([a-zA-Z0-9_\-\.\+]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$
Теперь осталось лишь протестировать то, что получилось:
$ echo "[email protected]" | awk '/^([a-zA-Z0-9_\-\.\+]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/{print $0}'
$ echo "[email protected]" | awk '/^([a-zA-Z0-9_\-\.\+]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/{print $0}'
Проверка адреса электронной почты с помощью регулярных выражений
То, что переданный awk текст выводится на экран, означает, что система распознала в нём адрес электронной почты.
Итоги
Если регулярное выражение для проверки адресов электронной почты, которое встретилось вам в самом начале статьи, казалось тогда совершенно непонятным, надеемся, сейчас оно уже не выглядит бессмысленным набором символов. Если это действительно так — значит данный материал выполнил своё предназначение. На самом деле, регулярные выражения — это тема, которой можно заниматься всю жизнь, но даже то немногое, что мы разобрали, уже способно помочь вам в написании скриптов, которые довольно продвинуто обрабатывают тексты.
В этой серии материалов мы обычно показывали очень простые примеры bash-скриптов, которые состояли буквально из нескольких строк. В следующий раз рассмотрим кое-что более масштабное.
Уважаемые читатели! А вы пользуетесь регулярными выражениями при обработке текстов в сценариях командной строки?
Примеры регулярных выражений
Ниже вы найдете множество примеров шаблонов, которые вы можете использовать и адаптировать для своих целей. Основные методы, используемые при создании каждого регулярного выражения, объясняются со ссылками на соответствующие страницы в учебнике, где эти концепции и методы объясняются очень подробно.
Если вы плохо знакомы с регулярными выражениями, вы можете взглянуть на эти примеры, чтобы увидеть, что возможно. Регулярные выражения очень сильны. Им действительно нужно время, чтобы научиться.Но вы быстро окупите это время, используя регулярные выражения для автоматизации задач поиска или редактирования в EditPad Pro или PowerGREP, или при написании скриптов или приложений на разных языках.
RegexBuddy предлагает самый быстрый способ освоить регулярные выражения. RegexBuddy проанализирует любое регулярное выражение и представит его вам в понятной и подробной схеме. Схема ссылается на учебник RegexBuddy по регулярным выражениям (тот же, что вы найдете на этом веб-сайте), где вы всегда можете получить подробную информацию одним щелчком мыши.>] *> (. *?) \ 1> будет соответствовать парам открытия и закрытия любого тега HTML. Обязательно отключите чувствительность к регистру. Ключевым моментом в этом решении является использование обратной ссылки \ 1 в регулярном выражении. Все, что находится между тегами, записывается во вторую обратную ссылку. Это решение также не будет соответствовать тегам, вложенным в себя.
Обрезка пробелов
Вы можете легко обрезать ненужные пробелы в начале и в конце строки или строк в текстовом файле, выполнив поиск и замену регулярного выражения.[\ T] + | [\ t] + $. Вместо [\ t], который соответствует пробелу или табуляции, вы можете расширить класс символов до [\ t \ r \ n], если вы также хотите убрать разрывы строк. Или вместо этого вы можете использовать сокращение \ s.
Более подробные примеры
Числовые диапазоны. Поскольку регулярные выражения работают с текстом, а не с числами, сопоставление определенных числовых диапазонов требует некоторой дополнительной осторожности.
Сопоставление числа с плавающей запятой. Также иллюстрирует распространенную ошибку, когда все в регулярном выражении делают необязательными.
Соответствие адресу электронной почты. Существует много споров о том, какое регулярное выражение должно соответствовать адресам электронной почты. Это прекрасный пример, показывающий, что вам нужно точно знать, что вы пытаетесь сопоставить (а что нет), и что всегда существует компромисс между сложностью регулярного выражения и точностью.
Соответствие IP-адресу.
Соответствующие действительные даты. Регулярное выражение, которое соответствует 31 декабря 1999 г., но не 31 13 декабря 1999 г.
Поиск или проверка номеров кредитных карт. Подтвердите номера кредитных карт, введенные в форму заказа.Найдите номера кредитных карт в документах для проверки безопасности.
Соответствие полных строк. Показывает, как сопоставить полные строки в текстовом файле, а не только часть строки, которая удовлетворяет определенному требованию. Также показано, как сопоставить строки, в которых конкретное регулярное выражение соответствует , а не .
Удаление повторяющихся строк или элементов. Показывает простое, но разумное использование скобок или обратных ссылок.
Примеры регулярных выражений для обработки исходного кода. Как согласовать общий синтаксис языка программирования, такой как комментарии, строки, числа и т. Д.
Два слова рядом друг с другом. Показывает, как использовать регулярное выражение для имитации оператора «рядом», который есть в некоторых инструментах.
Общие ловушки
Катастрофический возврат. Если ваше регулярное выражение, кажется, занимает вечность или просто приводит к сбою приложения, скорее всего, это привело к катастрофическому возврату. Решение обычно состоит в том, чтобы более точно указать, что вы хотите сопоставить, чтобы количество совпадений, которые должна попытаться выполнить движок, не увеличивалось экспоненциально.
Сделать все необязательным.Если все части в вашем регулярном выражении являются необязательными, он будет соответствовать строке нулевой длины где угодно. Ваше регулярное выражение должно будет выражать факты о том, что разные части являются необязательными в зависимости от того, какие части присутствуют.
Повторение группы захвата по сравнению с захватом повторяющейся группы. Повторение группы захвата захватит только последнюю итерацию группы. Захватите повторяющуюся группу, если вы хотите зафиксировать все итерации.
Смешивание кодов Unicode и 8-битных символов. Использование 8-битных кодов символов, таких как \ x80, с механизмом Unicode и строкой темы, может дать неожиданные результаты.
Сделайте пожертвование
Этот веб-сайт только что сэкономил вам поездку в книжный магазин? Сделайте пожертвование в поддержку этого сайта, и вы получите пожизненного доступа без рекламы к этому сайту!
.
Регулярные выражения Краткое руководство
Это краткое руководство поможет быстро освоить регулярные выражения. Очевидно, что это краткое введение не может объяснить все, что нужно знать о регулярных выражениях. Для получения подробной информации обратитесь к руководству по регулярным выражениям. Каждая тема в кратком руководстве соответствует теме в учебнике, поэтому вы можете легко переключаться между ними.
Многие приложения и языки программирования имеют собственные реализации регулярных выражений, часто с небольшими, а иногда и со значительными отличиями от других реализаций.Когда два приложения используют разные реализации регулярных выражений, мы говорим, что они используют разные «разновидности регулярных выражений». В этом кратком руководстве объясняется синтаксис, поддерживаемый наиболее популярными разновидностями регулярных выражений.
Текстовые шаблоны и совпадения
Регулярное выражение, или для краткости регулярное выражение, — это шаблон, описывающий определенный объем текста. На этом веб-сайте регулярные выражения выделены красным цветом как регулярные выражения. На самом деле это совершенно правильное регулярное выражение. Это самый простой шаблон, просто соответствующий регулярному выражению буквального текста.На этом сайте совпадения выделены синим цветом. Мы используем термин «строка» для обозначения текста, к которому применяется регулярное выражение. Строки выделены зеленым.
Символы со специальными значениями в регулярных выражениях выделяются разными цветами. Регулярное выражение (? 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 в разделе О кошках и собаках. Если регулярное выражение применяется снова, оно соответствует dog. Вы можете добавить столько альтернатив, сколько хотите: кошка | собака | мышь | рыба.
Чередование имеет самый низкий приоритет среди всех операторов регулярных выражений. 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.
Круглые скобки создают группу захвата. В приведенном выше примере есть одна группа.После совпадения группа номер один ничего не содержит, если был найден Set. Он содержит значение, если было найдено значение SetValue. Как получить доступ к содержимому группы, зависит от программного обеспечения или языка программирования, который вы используете. Нулевая группа всегда содержит полное совпадение регулярного выражения.
Использовать специальный синтаксис Set (?: Value)? для группировки токенов без создания группы захвата. Это более эффективно, если вы не планируете использовать содержимое группы. Не путайте вопросительный знак в синтаксисе группы без захвата с квантификатором.
Подробнее о группировке и захвате
Обратные ссылки
В регулярном выражении вы можете использовать обратную ссылку \ 1, чтобы сопоставить тот же текст, который был сопоставлен группой захвата. ([abc]) = \ 1 соответствует a = a, b = b и c = c. Больше ни с чем не совпадает. Если ваше регулярное выражение имеет несколько групп захвата, они нумеруются, считая их открывающие скобки слева направо.
Подробнее о обратных ссылках
Именованные группы и обратные ссылки
Если в вашем регулярном выражении много групп, отслеживать их количество может быть затруднительно.Сделайте ваши регулярные выражения более удобными для чтения, назвав группы. (?
Подробнее об именованных группах
Свойства Unicode
\ p {L} соответствует одному символу из данной категории Unicode. L означает букву. \ P {L} соответствует одному символу, не входящему в данную категорию Unicode. Вы можете найти полный список категорий Unicode в руководстве.
Дополнительные сведения о регулярных выражениях Unicode
Поисковый запрос
Поисковый запрос — это особый вид группы. Токены внутри группы сопоставляются нормально, но затем механизм регулярных выражений заставляет группу отказаться от совпадения и сохраняет только результат. Lookaround соответствует позиции, как якоря. Он не расширяет совпадение с регулярным выражением.
q (? = U) соответствует рассматриваемому q, но не в Ираке. Это позитивный взгляд на будущее. U не является частью общего совпадения регулярного выражения. Предварительный просмотр соответствует каждой позиции в строке перед u.
q (?! U) соответствует q в Ираке, но не подлежит сомнению. Это негативный взгляд вперед. Выполняется попытка использования токенов внутри опережающего просмотра, их совпадение отбрасывается, а результат инвертируется.
Чтобы посмотреть назад, используйте просмотр назад. Положительный просмотр назад (? <= A) b соответствует b в abc. Отрицательный просмотр назад (?
Внутри lookahead можно использовать полноценное регулярное выражение. Большинство приложений допускают только выражения фиксированной длины в ретроспективе.
Узнать больше о поиске
Синтаксис свободного пробела
Во многих приложениях есть опция, которая может быть помечена как «свободный интервал», «игнорировать пробелы» или «комментарии», что заставляет обработчик регулярных выражений игнорировать неэкранированные пробелы и разрывы строк и это заставляет символ # начинать комментарий, который длится до конца строки.Это позволяет вам использовать пробелы для форматирования вашего регулярного выражения таким образом, чтобы облегчить чтение людьми и, следовательно, упростить обслуживание.
Подробнее о свободных интервалах
Сделайте пожертвование
Этот веб-сайт только что сэкономил вам поездку в книжный магазин? Сделайте пожертвование в поддержку этого сайта, и вы получите неограниченного доступа к этому сайту без рекламы!
.
примеров — Учебник по регулярным выражениям
Примеры регулярных выражений!
RE для реального мира.
Введение
Регулярные выражения могут быть немного абстрактным понятием, чтобы вы могли понять. Давайте рассмотрим несколько реальных примеров, чтобы лучше понять, как они используются на самом деле и какие типы проблем вы можете решить с их помощью. Помните, что приведенные ниже примеры — это лишь часть того, что вы можете делать с регулярными выражениями.У них много применений, и вы действительно ограничены только своим воображением и творчеством.
В приведенных ниже примерах вы можете навести указатель мыши на разбивку, чтобы выделить различные компоненты.
Нависает на эту страницу.
Для создания функциональности на этой странице, где вы можете навести курсор на описания и примеры и увидеть, какие части регулярного выражения они ссылаются на небольшое количество Javascript, используется. Если вы хотите увидеть код, вы можете щелкнуть правой кнопкой мыши и «просмотреть исходный код», чтобы увидеть его.Я установил ID в соответствующих разделах, тогда Javascript использует регулярное выражение для извлечения соответствующих данных и на основе этого идентифицирует соответствующий контент, чтобы также выделить. Так, например, у меня есть элемент, обозначенный как eg1trigger3 . При наведении курсора на него используется регулярное выражение для извлечения номера примера (1) и номера триггера (3) следующим образом:
например (\ d +) триггер (\ d +)
В разбивке то есть:
- Начало предполагаемого идентификатора — например .
- Номер примера. Поместив его в скобки, мы сможем использовать его в Javascript позже.
- триггер секция идентификатора.
- Номер триггера. Поместив его в скобки (аналогично номеру примера), мы можем использовать его в Javascript позже.
Номера кредитных карт
Проверка формы — это область, где действительно полезны регулярные выражения. Этот и несколько следующих примеров здесь действительно полезны.
Итак, мы знаем, что номер кредитной карты состоит из 16 цифр и обычно делится на 4 группы по 4 цифры. Разве вы не ненавидите, когда вам дают только одно поле и не говорят, принимает ли оно число как одно большое число или четыре группы из четырех цифр. Что, если бы он мог элегантно справиться с обоими. Пока мы это делаем, давайте также сделаем так, чтобы разделителем был пробел, тире или запятая.
\ d {4} [-,]? \ D {4} [-,]? \ D {4} [-,] \ d {4}
В разбивке то есть:
- 4 цифры, за которыми следует
- либо тире, либо запятая, либо пробел, ноль или один раз, за которым следует
- 4 цифры, за которыми следует
- либо тире, либо запятая, либо пробел, ноль или один раз, за которым следует
- 4 цифры, за которыми следует
- либо тире, либо запятая, либо пробел, ноль или один раз, за которым следует
- 4 цифры
Если вам нужны разные разделители, достаточно просто изменить то, что находится внутри операторов диапазона.Этот шаблон также легко адаптировать к другим элементам, основанным на цифрах, таким как номера участников, IP-адреса и т. Д.
Это можно расширить для поддержки различных марок кредитных карт. Это потому, что каждый бренд имеет уникальные характеристики, которые мы можем идентифицировать.
Адреса электронной почты
Адреса электронной почты — интересный случай. В зависимости от того, насколько педантичным вы хотите быть, есть множество подходов. Что составляет действительный синтаксис, может быть довольно сложным.Вот менее педантичный подход.
[a-zA-Z0-9. + -_] + @ [a-zA-Z0-9 .-] + \. [A-zA-Z] {2,63}
В разбивке то есть:
- Имя получателя, за которым следует
- Символ @, за которым следует
- Основная часть домена, за ней следует
- Доменная часть верхнего уровня домена
Вам может быть интересно, почему раздел домена верхнего уровня состоит от 2 до 63 символов, а не от 2 до 4 символов.Раньше все было просто: почти все домены были чем-то вроде .com или .net, с, возможно, .au для обозначения страны. Теперь все стало глупо, и существуют такие домены, как .sandvikcoromant (с большей вероятностью). Официальная спецификация допускает до 63 символов для домена верхнего уровня, поэтому, вероятно, безопаснее всего проверить это.
Обработка HTML
Такие вещи, как HTML, где наш контент следует определенному синтаксису, отлично подходят для использования регулярных выражений, когда мы хотим идентифицировать определенные элементы.>] * alt =). *>. * \ 1>
В разбивке то есть:
- Имя открывающего тега. Мы помещаем это в скобки, чтобы мы могли сопоставить его и в конце.
- Другой возможный материал в открывающем теге, атрибутах и т. Д.
- Контент, который не является тегом img .
- Тег img . Использование операторов диапазона для идентификации в нижнем регистре, в верхнем регистре или в смеси.
- Здесь мы используем отрицательный просмотр вперед, чтобы убедиться, что alt = не находится где-то после тега img перед закрывающим > .
- Возможное содержимое после вкладки img и до закрывающего тега.
- Закрывающий тег. \ 1 становится тем же, что и в скобках вокруг имени открывающего тега.
Давайте рассмотрим пример, чтобы проиллюстрировать это (наведите указатель мыши на разделы, чтобы увидеть, как они совпадают с регулярным выражением выше):
Это фотография моей собаки . Он потрясающий.
.Учебное пособие по регулярным выражениям
— Узнайте, как использовать регулярные выражения
Из этого туториала Вы узнаете все, что нужно знать для создания эффективных регулярных выражений, экономящих время. Он начинается с самых основных концепций, так что вы можете следовать этому руководству, даже если вы еще ничего не знаете о регулярных выражениях.
Обучение на этом не заканчивается. Он также объясняет, как работает механизм регулярных выражений, и предупреждает вас о последствиях. Это поможет вам быстро понять, почему конкретное регулярное выражение не выполняет то, что вы изначально ожидали.Это избавит вас от множества догадок и головной боли, когда вам нужно написать более сложные регулярные выражения.
Что такое регулярные выражения — терминология
По сути, регулярное выражение — это шаблон, описывающий определенный объем текста. Их название происходит от математической теории, на которой они основаны. Но мы не будем углубляться в это. Обычно вы найдете имя, сокращенное до «regex» или «regexp». В этом руководстве используется «регулярное выражение», потому что множественное число «регулярные выражения» легко произносится.На этом веб-сайте регулярные выражения выделены красным цветом как регулярные выражения.
Этот первый пример на самом деле является вполне допустимым регулярным выражением. Это самый простой шаблон, просто соответствующий регулярному выражению буквального текста. «Совпадение» — это фрагмент текста или последовательность байтов или символов, соответствие которой было обнаружено программой обработки регулярных выражений. На этом сайте совпадения выделены синим цветом.
\ b [A-Z0-9 ._% + -] + @ [A-Z0-9 .-] + \. [A-Z] {2,} \ b — более сложный узор. Он описывает серию букв, цифр, точек, подчеркиваний, знаков процента и дефисов, за которыми следует знак at, за которым следует еще одна серия букв, цифр и дефисов, за которыми, наконец, следует одна точка и две или более букв.Другими словами: этот шаблон описывает адрес электронной почты. Это также показывает выделение синтаксиса, примененное к регулярным выражениям на этом сайте. Границы слов и квантификаторы — синие, классы символов — оранжевые, а экранированные литералы — серые. Вы увидите дополнительные цвета, например зеленый для группировки и фиолетовый для мета-токенов позже в этом руководстве.
С помощью приведенного выше шаблона регулярного выражения вы можете искать в текстовом файле адреса электронной почты или проверять, выглядит ли данная строка как адрес электронной почты.В этом руководстве термин «строка» используется для обозначения текста, к которому применяется регулярное выражение. На этом сайте они выделены зеленым цветом. Термин «строка» или «символьная строка» используется программистами для обозначения последовательности символов. На практике вы можете использовать регулярные выражения с любыми данными, к которым вы можете получить доступ, используя приложение или язык программирования, с которым вы работаете.
Различные механизмы регулярных выражений
«Механизм» регулярных выражений — это часть программного обеспечения, которое может обрабатывать регулярные выражения, пытаясь сопоставить шаблон с заданной строкой.Обычно движок является частью более крупного приложения, и у вас нет прямого доступа к нему. Скорее приложение вызывает его, когда это необходимо, чтобы убедиться, что правильное регулярное выражение применяется к нужному файлу или данным.
Как обычно в мире программного обеспечения, разные механизмы регулярных выражений не полностью совместимы друг с другом. Синтаксис и поведение конкретного движка называется разновидностью регулярных выражений. В этом руководстве рассматриваются все популярные разновидности регулярных выражений, включая Perl, PCRE, PHP,.NET, Java, JavaScript, XRegExp, VBScript, Python, Ruby, Delphi, R, Tcl, POSIX и многие другие. Учебник предупреждает вас, когда эти варианты требуют другого синтаксиса или показывают другое поведение. Даже если ваше приложение явно не рассматривается в руководстве, оно, вероятно, использует разновидность регулярных выражений, о которой идет речь, поскольку большинство приложений разрабатываются с использованием одной из упомянутых сред программирования или библиотек регулярных выражений.
Испытайте регулярные выражения в первую очередь
Вы можете легко попробовать следующее самостоятельно в текстовом редакторе, поддерживающем регулярные выражения, таком как EditPad Pro.Если у вас нет такого редактора, вы можете загрузить бесплатную ознакомительную версию EditPad Pro, чтобы опробовать его. Механизм регулярных выражений EditPad Pro полностью работает в демонстрационной версии.
В качестве быстрой проверки скопируйте и вставьте текст этой страницы в EditPad Pro. Затем выберите в меню Поиск | Панель многострочного поиска. На панели поиска, которая появляется внизу, введите регулярное выражение в поле с надписью «Search Text». Установите флажок «Регулярное выражение» и нажмите кнопку «Сначала найти».Это крайняя левая кнопка на панели поиска. Посмотрите, как движок регулярных выражений EditPad Pro находит первое совпадение. Нажмите кнопку «Найти далее», которая находится рядом с кнопкой «Найти сначала», чтобы найти другие совпадения. Если совпадений больше нет, значок кнопки «Найти далее» кратковременно мигает.
Теперь попробуйте выполнить поиск с помощью регулярного выражения reg (ular expressions? | Ex (p | es)?). Это регулярное выражение находит все имена в единственном и множественном числе, которые я использовал на этой странице, чтобы сказать «регулярное выражение». Если бы у нас был только простой текстовый поиск, нам бы потребовалось 5 поисков.С регулярными выражениями нам нужен всего один поиск. Регулярные выражения экономят ваше время при использовании такого инструмента, как EditPad Pro. Выберите «Подсчет совпадений» в меню «Поиск», чтобы узнать, сколько раз это регулярное выражение может совпадать с файлом, который вы открыли в EditPad Pro.
Если вы программист, ваше программное обеспечение будет работать быстрее, так как даже простой движок регулярных выражений, применяющий вышеуказанное регулярное выражение один раз, превзойдет современный алгоритм поиска по тексту в пять раз. Регулярные выражения также сокращают время разработки.С движком регулярных выражений требуется только одна строка (например, в Perl, PHP, Python, Ruby, Java или .NET) или пара строк (например, в C с использованием PCRE) кода, чтобы, скажем, проверить, введены ли данные пользователем выглядит как действующий адрес электронной почты.
Regex Tutorial Содержание
Сделайте пожертвование
Этот веб-сайт только что сэкономил вам поездку в книжный магазин? Сделайте пожертвование на поддержку этого сайта, и вы получите неограниченного доступа к этому сайту без рекламы!
.
Добавить комментарий