Регулярний вираз будь-який рядок. Практичне введення в регулярні вирази для новачків

Легке і веселе введення в теорію регулярних виразів від веб-розробника Джоша Хоукінса Regex, що охоплює всі основні моменти, які потрібно знати новачкові.

Ви колись працювали з рядками? Так-так, з тими «масивами символів», які ми всі знаємо і любимо. Якщо ви програмували на чомусь, крім чистого С, з упевненістю можна припустити, що працювали, причому не раз. Але що, якщо ви маєте справу з безліччю рядків? Або з рядками, що згенеровані не вашою програмою? Наприклад, ви зчитуєте електронного листа, парсі аргументи командного рядкаабо читаєте інструкції, написані людиною, і вам потрібен структурований метод роботи з усім цим.

Безперечно, ви можете перебирати кожне слово або символ у всіх рядках. І, ймовірно, подібний код буде досить простим для розуміння. Але в масштабних додатках це може бути надмірно громіздким та надто ресурсозатратним.

Вступ. Регулярний вираз

Не забираючись у нетрі глибокої інформатики, давайте дамо визначення регулярного вираження.

  • Регулярні висловлювання - це правила, що описують певну формальну мову.
  • Регулярні вирази - різновид формальної мови, яка може бути оброблена кінцевим автоматом.

Існує безліч інших визначень регулярних виразів, так що якщо сказаного вище для щастя вам недостатньо, можете витратити пару хвилин на гуглінг.

Вступ. Regex

Зараз, можливо, ми підійшли до місця, де настав час злякатися (якщо ви досі цього не зробили). Ми розглянемо різницю між тим, що входить у поняття регулярних висловів мовами програмування, що - фундаментальної інформатикою.

  • Регулярні висловлювання з погляду інформатики - правила, що пояснюють формальну мову.
  • Регулярні висловлювання з погляду мов програмування - граматика, що висловлює, переважно, деякий контекстно-залежна мова.

Контекстно-залежні мови відчутно складніші і потужніші, тому з цього моменту умовимося називати регулярні вирази в термінах мов програмування „regex“, щоб підкреслити їхню відособленість від формальних мовв цілому.

Вчимося писати regex-и

Регулярні вирази описуються за допомогою двох слешів ( // ) і відповідають рядкам, які підходять під шаблон, укладений між ними. Наприклад, /Hi/ відповідає „Hi“, тому ми можемо перевірити відповідність деякого рядка цьому шаблону.

Символи в регулярних виразахзіставляються у порядку, у якому вводяться. Так /Hello world/ відповідає рядку „Hello world“.

Можна спростити пошук довільних слів, додавши трохи regex-магії: \w відповідає будь-якому «слову», складеному лише з літер. За таким самим принципом ідентифікуються числа: \d .

Приклад 1

Чудово, тепер ми можемо порівнювати рядки або перевіряти їхню відповідність деякому патерну. Що далі? Чи можуть регулярні вирази виконувати ще якісь функції?

Будьте впевнені! Скажімо, ми написали IRC-чат бота, який реагує, якщо хтось напише „Josh“. Наш бот сканує кожне повідомлення, доки не дочекається збігу. Тоді бот відповідає: „Woah, I hope you aren't talking bad about my pal Josh!“ («О, сподіваюся, ви не говоритимете погано про мого приятеля Джош!»). Тому що з Джошами дружать лише роботи.

Для порівняння рядків наш бот використовує шаблон /Josh/ . Одного разу хтось на ім'я Eli вимовить: "Eli: Josh, do you really need that much caffeine?" ("Елі: Джош, тобі дійсно необхідна така кількість кофеїну?"). Наш бот нагострить вушка, виявить збіг, видасть свою несподівану відповідь, чим досить налякає Елі. Місія виконана! Чи ні?

Що, якби наш бот був розумнішим? Що, якби він, наприклад, звертався до того, хто говорить на ім'я? Щось на кшталт „Woah, I hope you aren't bad-mouthing my buddy Josh, Eli.“ («О, сподіваюся, ти не будеш злословити про мого приятеля Джош, Елі?»).

Квантифікатори (повторні символи)

0 і більше

Ми можемо зробити це ... Але для початку потрібно усвідомити кілька моментів. Перший - квантифікатори(для символів, що повторюються). Можна використовувати * для позначення 0 або декількох символів після. Наприклад, /a*/ може відповідати „aaaaaaa“, а також „“. Так, ви не дочули: воно відповідатиме порожньому рядку.

* служить для позначення чогось необов'язкового, оскільки символ, якому вона відповідає, існувати не зобов'язаний. Але може. І не раз (теоретично, безліч разів).
Можна позначити „Josh“ за допомогою /Josh/ , але ми можемо також задати „Jjjjjjjjjosh“ або „osh“ патерном /J*osh/ .

1 і більше

Для позначення одного і більше символів використовується + . Він ефективно працює за тим же принципом, що і * , за винятком того, що існування хоча б одного символу більше не є опціональним: повинен бути присутнім на Крайній міріодин.

Таким чином, ми можемо задати шаблон /J+osh/ рядки „Josh“ або „Jjjjjjjjjosh“, але не „osh“.

Метасимволи

Прекрасно, ми вже багато в чому розв'язали собі руки. Можливо, зараз хтось волає «Джоооооош», якщо вже досить розлютився…

Але що, якщо він сердиться настільки сильно, що навіть кілька разів ударив обличчям по клавіатурі? Як нам позначити «ааавыопшадлорвпт», не знаючи заздалегідь, наскільки міток його ніс?
За допомогою метасимволів!

Метасимволи дозволяють задавати абсолютно ЩО ЗАВЖДИ. Їх синтаксис - . . (Так, крапка. Просто крапка.). Б'ємося об заклад, ви часто користуєтеся нею, так що не соромтеся позначати їй кінець речення.

Можна задати „Joooafhuaisggsh“ виразом /Jo+.*sh/ комбінуючи отримані раніше знання про символи, що повторюються, і метасимволів. Якщо бути точними, цей вираз відповідає одній „J“, одному чи більше „o“, нулю або кільком метасимволам, а також одній „s“ та одній „h“. Ці п'ять блоків підводять нас до того, що ми називаємо…

…групами символів

Групи символів- це символьні блоки, у яких важлива послідовність складових. Вони розглядаються як єдине ціле. Використовуючи * або + , Ви фактично задаєте послідовність повторюваної групи знаків, а не тільки останнього символу.

Це корисно зрозуміти і як окрему техніку, але більшу функціональність вона знаходить у поєднанні з символами, що повторюються. Групи символів задаються за допомогою круглих дужок (так, цих хлопців).
Допустимо, ми хочемо повторювати „Jos“, але не „h“. щось на кшталт „JosJosJosJosJosh“. Це можна зробити виразом /(Jos)+h/ . Просто, чи не так?

Але нарешті… Повертаючись до нашого першого прикладу, як отримати ім'я Елі в нашому IRC чаті з відправленого нею повідомлення?

Групи символів можуть служити для запам'ятовування підрядків. Для цього зазвичай роблять щось на зразок \1 щоб визначити першу задану групу.

Наприклад, /(.+) \1/ особливий випадок. Тут ми бачимо набір випадкових символів, що повторюється один або більше разів, пробіл після нього, а потім повторення точно такого ж набору ще раз. Так що такий вираз буде відповідати „abc abc“, але не „abc def“, навіть якщо „def“ сам собою відповідає (.*) .

Запам'ятовування збігів дуже потужна штука, і вона, ймовірно, зводиться до самої корисної функціїрегулярних виразів.

Приклад 2

Фух ... Нарешті можна повернутися наприклад з IRC чат роботом. Давайте застосуємо наші знання на практиці.

Якщо ми хочемо вичепити ім'я відправника повідомлення, коли він пише „Josh“, наш вираз буде виглядати приблизно так: /(\w+): .*Josh.*/ , і ми зможемо зберегти результат у змінній у нашій мові програмування для відповіді.

Давайте розглянемо наш регулярний вираз. Тут одна або більше літер, наступних за « : », 0 або більше символів, „Josh“ та знову 0 або більше символів.

Примітка: /.*word.*/ — простий спосіб задати рядок, що містить „word“, причому інші символи можуть бути присутніми, а можуть і ні.

На Python це буде виглядати так:
import re
pattern = re.compile(ur"(\w+): .*Josh.*") # Our regex
string = u"Eli: Josh go move your laundry" # our string
matches = re.match(pattern, string) # Test the string
who = matches.group(1) # Get who said the message
print(who) # "Eli"
Зауважте, що ми використовували .group(1) так само, як \1 . У цьому немає нічого нового, за винятком використання регулярних виразів у Пітоні.

Початок та кінець

До цього моменту ми припускали, що шукані підрядки можуть бути в будь-якому місці рядка. Наприклад, /(Jos)+h/ відповідає будь-якому рядку, який містить „Jos-повторюване-h“ у довільному місці.

А якщо нам необхідно, щоб рядок починався з цього шаблону? Це можна позначити як /^(Jos)+h/ , де ^ відповідає початку рядка. Аналогічно, $ позначає кінець рядка.

Тепер, якщо ми хочемо задати рядок, що містить лише „Jos-повторюване-h“, то напишемо /^(Jos)+h$/ .

Перелік виразів

Уявіть, що ви пишете регулярне вираження рецепту бутерброду. Ви не знаєте, воліє замовник білий хліб або чорний, але вибрати все одно доведеться лише один. Як додати можливість вибору regex? За допомогою перерахувань!

Вони дозволяють задавати набори можливих значень групи символів. Це виглядає так: (white|wheat) . У контексті нашого прикладу з бутербродом буде прийнято один з варіантів - або "white", або "wheat".

Для позначення перерахувань дещо по-іншому використовують [квадратні дужки]. Замість усього рядка тут варіантом є кожен її символ. Це може бути корисним для складних регулярних виразів, тому що ви можете замінити один символ більш складним набором.

Модифікатори

Ми говорили про regex з /двома слешами/, вірно? Ми знаємо, що між ними, але що має бути зовні?

Несподіваний поворот: нічого!

…зліва. Права сторона, Навпаки, може містити безліч, безліч всього корисного. Навіть соромно, що ми так довго не сказали про це жодного слова!
Модифікаторизадають правила, якими застосовуються регулярні висловлювання.

Ось список основних модифікаторів (з Regex101.com):

Модифікатор Назва Опис
g global Усі збіги
m multi-line ^ і $ відповідають початку та кінцю кожного рядка
i insensitive Реєстронезалежне порівняння
x extended Прогалини та текст після # ігноруються
X extra \ з довільною літерою, що не має особливого значення, повертає помилку
s single line Ігнорує символи нового рядка
u unicode Рядки-шаблони обробляються як UTF-16
U ungreedy За замовчуванням у regex використовується «лінива квантифікація». Модифікатор U робить квантифікацію «жадібною»
A anchored Шаблон форсується до ^
J duplicate Дозволяє імена субпаттернів, що дублюються.

Для наочності всі попередні приклади були регістрозалежними. Це означає, що якщо замінити хоча б одну малу літеру на заголовну або навпаки, рядок перестане задовольняти шаблон. Але можна зробити його реєстронезалежним за допомогою модифікатора i .

Припустимо, Елі розлютилася настільки, що почала бомбити чат повідомленнями з Буквами різних реєстрів. Це нас не лякає, бо й уже тут! Ми можемо легко задати гнівливий вираз „I hAate LiVing witH JOSH!!!“ патерном /i ha+te living with josh!+/i . Тепер наші regex стали легше читані, а також набагато потужніші та корисніші. Чудово!

Ви можете самостійно грати з різними модифікаторами. На мій погляд, в цілому вам найбільше знадобиться igm .

Що далі?

Сподіваюся, ця стаття дозволила по-іншому поглянути на роботу з рядками та зробити її розумнішою. Ми лише трохи пройшлися поверхнею, але ви вже навчилися використовувати regex для вирішення деяких завдань.

Існує безліч символів та їх поєднань, що використовуються у регулярних виразах. Зазвичай ви натикатиметеся на них під час вивчення Stack Overflow, але про значення деяких можна здогадатися і з попередніх прикладів (наприклад, \n - Символ переходу на новий рядок). База закладена, але вивчити доведеться ще багато.

Знайти повний списокпоєднань символів, а також перевірити свої знання можна.
Якщо це здалося вам простіше простого, спробуйте regex-кросворди. Вони справді змусять вас попітніти.

Після точки

Ця стаття – переклад гайда Джоша Хоукінса. Джош – пристрасний веб-розробник з Алабами. Він почав програмувати у віці дев'яти років, зосередившись на відеоіграх, десктопних та деяких мобільних додатках. Однак, під час стажування у 2015, Джош відкрив для себе веб-розробку та увірвався у світ опенсорсу, пов'язаного з цією областю.

Раніше з регулярних виразів я використав лише (.*) :) Кілька друзів настійно радили мені розібратися у цьому питанні. Але не розуміючи, де їх можна застосовувати, я відкладав це до найкращих часів.

Все змінилося, коли мені довелося щільніше працювати з Google Analyticsі Google Tag Manager в Netpeak.

Без розуміння регулярних виразів складно уявити собі нормальне налаштування фільтрів, сегментів користувача в GA або правил в GTM.

Давайте розберемося, з чого варто розпочати вивчення регулярних виразів новачкові.

Що таке регулярні вирази

Регулярні вирази (regular expressions, RegExp) - набори символів, які застосовуються для пошуку текстових рядків, що відповідають необхідним умовам. Результат застосування регулярного виразу - підмножина даних, відібрана згідно з логікою, закладеною у виразі. Регулярні вирази застосовуються в будь-яких задачах пошуку в безлічі даних, для яких потрібно отримувати вичавки за певними правилами.

Синтаксис регулярних виразів

Більшість символів у регулярних виразах представляють себе, крім групи спеціальних символів « \ / ^ $ . | ? * + () ( )». Якщо ці символи потрібно подати як символи тексту, їх слід екранувати косою рисою «\».

Якщо ці спецсимволи зустрічаються без зворотної косої межі, значить у них особливі значення в регулярних виразах:

  • "^" - Каретка, циркумфлекс або просто галочка. Початок рядка;
  • "$" - Знак долара. Кінець рядка;
  • "." - крапка. Будь-який символ;
  • «*» – знак множення, зірочка. Будь-яка кількість попередніх символів;
  • "+" - плюс. 1 чи більше попередніх символів;
  • «?» - знак запитання. 0 чи 1 попередніх символів;
  • "()" - круглі дужки. Угруповання конструкцій;
  • «|» - вертикальна лінія. Оператор "АБО";
  • "" - квадратні дужки. Будь-який із перерахованих символів, діапазон. Якщо перший символ у цій конструкції - «^», то масив працює навпаки - символ, що перевіряється, не повинен збігатися з тим, що перераховано в дужках;
  • "( )" - фігурні дужки. Повторення символу кілька разів;
  • «\» - зворотний сліш. Екранування службових символів.

Також існують спеціальні метасимволи, ними можна замінити деякі готові конструкції:

  • \ b - Позначає не символ, а кордон між символами;
  • \d - Цифровий символ;
  • \ D - Нецифровий символ;
  • \s - пробельний символ;
  • \S - непробільний символ;
  • \w - літерний або цифровий символ або знак підкреслення;
  • \W - будь-який символ, крім буквеного або цифровий символабо знак підкреслення.

П'ять способів протестувати свої знання про регулярні висловлювання

Під час вивчення регулярних висловів дуже важлива практика. Чим більше практикуєшся, тим швидше починаєш будувати потрібні конструкції та вирішувати поставлені завдання.

1. Вивчаємо регулярні вирази у текстовому редакторі

  • в більшості випадків спецсимволи не потрібно екранувати;
  • Notepad++ зберігає конструкції попередніх запитів;

2. Перевіряємо знання регулярних виразів у Regex

Щоб просканувати все URL адреситільки першого рівня вкладеності, у сервісі потрібно задати такі налаштування:

Вирішив написати шпаргалку за регулярними виразами. Раптом я колись їх забуду. Крім того, цей пост можна вважати продовженням до моєї серії уроків Perl .

1. Введення

Пара слів для тих, хто не зовсім знає, про що йде мова. Ви бачили колись маски імен файлів - всякі там *.html, filename. (txt | csv) і тд? Так от, регулярні вирази — це ті самі маски, тільки складніші. В умілих руках регулярні вирази можуть бути неймовірно потужним інструментом. Так чи інакше вони використовуються у 95% моїх скриптів.

Багато хто небезпідставно вважає, що регулярні висловлювання — це швидше самостійна мовапрограмування, ніж частина будь-якої мови. Регулярні вирази є в Perl, PHP, Python, JavaScript, конфігураційних файлів Apache… Залежно від мови, можуть мати невеликі відмінності в синтаксисі регулярних виразів, але основні ідеї скрізь одні й ті самі.

Тому, незважаючи на те, що всі приклади в нотатці написані на Perl, наведена інформація стане в нагоді програмістам, які використовують у своїй роботі будь-яку іншу мову. Наприклад, такий код на PHP:

if (preg_match ("//", $text)) (
// у тексті є цифри
) else (
// У тексті немає жодної цифри
}

і такий - на Perl:

if ($text =~ // ) (
# у тексті є цифри
) else (

}

роблять одне й те саме. Як не складно здогадатися за коментарями у коді, тут Йде перевірка, чи містить рядок $text хоча б одну цифру.

2. Прості приклади

Як завжди, будемо вчитися на прикладах. Квадратні дужкиу регулярних виразах означають «тут має бути один із перелічених символів». Наприклад, наведеному вище виразу відповідає будь-який рядок, що містить хоча б одну цифру. Аналогічно, виразу відповідає будь-який рядок, що містить хоча б одну з перших трьох літер латинського алфавіту. Щоб позначити будь-який символ, крімзаданих, використовується запис [^abcdef], тобто з символом кришкивідразу за квадратною дужкою, що відкривається.

Нехай нам потрібно перевірити, чи рядок містить будь-який символ латинського алфавіту. Перелічувати всі 26 букв не зовсім зручно, правда? Спеціально для таких випадків у регулярних виразах можна використовувати тире у квадратних дужкахдля позначення впорядкованої множини символів. Виразу буде відповідати будь-який рядок, що містить хоча б одну малу літеру латинського алфавіту. За аналогією, наведений раніше приклад із цифрами можна записати коротше:

if ($text =~ // ) (
# у тексті є цифри
) else (
# у тексті немає жодної цифри
}

І ще кілька прикладів:

if ($text =~ // ) (
# у тексті є цифри та/або малі літери
# підходить: abc, ZZaZZ, ===17
# не підходить: EPIC FAIL, @^*!@#
}

if ($text =~ /[^0-9]/ ) (
# у тексті є символи, відмінні від цифр
# підходить: abc, 123abc456, 0x1111111111
# не підходить: 123, 123456, 9999999999
}

if ($text =~ // ) (
# у тексті є літери латинського алфавіту
# підходить: ___Abba___, zyx
# не підходить: 0123, ^_^
}

if ($text =~ // ) (
# текст містить цифри та літери від A до F
# підходить: ***777***, DeadC0de, intel, 0_o
# не підходить: Xor, wiki
}

Ускладнимо завдання. Тепер нам потрібно перевірити не просто наявність чи відсутність певних символів, а відповідність рядка певному формату. Ось кілька простих прикладів:

if ($text =~ /num=/ ) (
# підходить: num=1, some_num=000, bebenum=2(&^*
# не підходить: NUM = 1, my_num = -1, num = abc
}

if ($text =~ / / ) {
# підходить:
# zzz zzz
#
# не підходить:
#
#
}

Уважний читач поцікавиться, що це за знак плюсустоїть в останньому регулярному виразі? Цей символ означає один або більше символів, зазначених перед цим плюсом. Майже те саме означає символ зірочка«від нуляскільки завгодно символів, вказаних перед зірочкою». Наприклад, виразу A+буде відповідати послідовність з одного і більше символів A, а виразу * — будь-яка кількість цифр, у тому числі жодної.

Іноді кількість символів потрібно вказати точніше. Це можна зробити за допомогою фігурних дужок . Наприклад, виразу {8} відповідає будь-яка послідовність з рівно восьми цифр, а виразу {3,8} - Послідовність, що містить від 3-х до 8-и символів латинського алфавіту.

Число на другій позиції можна не вказувати. Тобто вираз {3,} також може мати місце. Воно означає «щонайменше трьох малих літер латинського алфавіту». Вираз {0,} повністю аналогічно зірочці, а {1,} - Плюсу. Вираз {0,1} можна записати коротше, використовуючи знак питання.

Приклад (не найпростіший, зате цікавий):

if ($text =~ // ) {
# підходить:
#dfgd dfgdfg
#
# не підходить:
#
#
}

Якщо від цього прикладу у вас закипають мізки, саме час трохи попрактикуватися в регулярних виразах шляхом написання тестових програмок. Інакше від подальшого прочитання у вас буде каша в голові. Якщо поки що все зрозуміло, ідемо далі.

3. Як видерти шматок рядка?

Символ вертикальної риси(він же «пайп» або просто «палиця») у регулярних виразах означає «або». Наприклад, виразу {20}|{25} відповідають усі рядки, що містять 20 символів латинського алфавіту або 25 цифр поспіль. Зазвичай цей символ використовується спільно з круглими дужками, призначені для угруповання частин регулярного виразу. Приклад:

if ($filename =~ /backup(19|20)(2)-(2)-(2)/) {
# підходить: backup2011-04-01, backup1999-01-13
# не підходить: backup1873-12-12, backup2101-07-07
}

У круглих дужок є ще одна функція. З їх допомогою можна видерти шматки відповідних рядків. У PHP результатзберігається в змінну, вказану третім аргументом функції preg_match. У Perl збіги для 1-ої, 2-ої … 9-ої пари дужок зберігаються в змінні $1, $2, …, $9 . Але зручніше використовувати таку конструкцію:

if (my ($y, $m, $d) =
$filename =~ /backup((4))-((2))-((2))/) {
print;
}

Запитується, під яким номером шукати збіг у масиві, що повертається, якщо регулярний вираз містить вкладенідужки? Все просто — збіги повертаються в тому ж порядку, в якому йдуть дужки. Приклад:

my $filename = "./dumps/backup2011-04-01.tgz";
$filename =~ /backup((20|19)(2))-((2))-((2))/;
print "$1, $2, $3, $4 \n ";
# виведе: 2011, 20, 04, 01

Іноді хотілося б згрупувати якусь частину висловлювання, але з повертати її. Для цього відразу за дужкою, що відкривається, потрібно написати послідовність із знака питання та двокрапки. Приклад:

if (my ($y, $m, $d) =
$filename =~ /backup((?:20|19)(2))-((2))-((2))/) {
print "year=$y, month=$m, day=$d\n";
}

Також за круглими дужками може слідувати знак питання, плюс або зірочка, що означають, що конструкція, зазначена в дужках, необов'язкова, повинна повторюватися 1+ разів або повинна повторюватися 0+ разів відповідно. Використання фігурних дужок за круглими також припустимо.

4. Початок та кінець рядка

Часто буває корисним позначити в регулярному виразі місце, де має починатися і/або закінчуватися рядок. Перше робиться за допомогою символ кришкина початку виразу, друге - за допомогою доларав кінці. Приклади:

if ($text =~ /^*/ ) (
# текст, що починається з десяткової цифри
# підходить: 3, 801403, 6543bebebe
# не підходить: 0275, -123, abc11111
}

if ($text =~ /^0x(1,8)$/ ) (
# шістнадцяткове числоу C-нотації
# підходить: 0x5f3759df, 0xDEADBEEF
# не підходить: 0x1234xxx, xxx0x5678, xxx0x9ABCxxx
}

Чи не складно, правда? Зверніть увагу, що під час перевірки полів веб-форм, аргументів функції перед підстановкою їх у SQL-запит і так далі, обов'язковослід перевіряти всюрядок, як це зроблено в останньому регулярному виразі.

Примітка:Якщо когось цікавить, що це за магічні числа 0x5f3759df і 0xDEADBEEF , звертайтеся до Вікіпедії.

5. Спеціальні символи

Крім названих спеціальних символів слід особливо відзначити точку. Вона означає будь-якийсимвол, крім нового рядка. Приклад використання:

if (my ($name ) = $arg =~ /^--name=(.+)$/ ) (
print "Hello, $name! \n ";
}

За умовчанням регулярні висловлювання виробляють так званий жадібний розбір. Іншими словами, шукаються збіги максимальної довжини. Коли ми використовуємо крапку, можуть виникнути проблеми. Наприклад, нам потрібно видерти деякий текст із сотні HTML-сторінок приблизно такого змісту:

<span > Text<em > text</ em > text</ span > Source: http://сайт/</ span >

Наступний код поверне нам не те, що хотілося б:

# у регулярному вираженні міститься слеш, тому
# доводиться використовувати замість нього інший обмежувач
(.*)#;
print $text;
# виведе найбільш довгий збіг:
# Text text textSource: http://сайт/

А ось що станеться, якщо відключити жадібний розбір (увага на знак питання):

my ($text) = $data =~ m # (.*?)#;
print $text;
# виведе перший збіг:
# Text text text

Так, наступні рядкироблять одне й те саме:

# Звичайна запис ...
$text =~ /({4})-({2})-({2})/ ;
# насправді - лише скорочення оператора m//
$text =~ m/((4))-((2))-((2))/;
# замість слеша можна використовувати різні дужки:
$text =~ m (([0-9](4))-([0-9](2))-([0-9](2)));
$text =~ m< ([ 0 - 9 ] { 4 } ) - ([ 0 - 9 ] { 2 } ) - ([ 0 - 9 ] { 2 } ) >;
$text =~ m [([0-9](4))-([0-9](2))-([0-9](2))];
$text =~ m(([0-9](4))-([0-9](2))-([0-9](2)));
# або навіть такі символи:
$text =~ m! ([0-9] (4)) - ([0-9] (2)) - ([0-9] (2))!;
$ text = ~ m | ([0-9] (4)) - ([0-9] (2)) - ([0-9] (2)) |;
$text =~ m #({4})-({2})-({2})#;
а також кришку, лапки, двокрапку, кому, точку, ...

Навіщо знадобилося стільки способів запису регулярних виразів? Уявіть, що вираз містить слеші, крапки, коми та інші символи, але не містить знака оклику. Тоді, очевидно, ми не можемо використовувати для позначення початку та кінця регулярного висловлювання слеші, крапки тощо, зате знак оклику- можемо.

Часто в регулярних виразах доводиться використовувати зворотний слеш. Поставлений перед точкою, дужкою, плюсом, кришкою та іншими символами він означає «наступний символ означає саме символ, а не щось інше». Наприклад, ось як можна визначити розширення файлу на його ім'я:

# Екранована зворотним слешем точка
# означає саме точку, а не "будь-який символ"
my ($ext) = $fname =~ /\.(+)$/ ;
print "file name: $fname, extension: $ext\n";

Крім того, зворотний слеш використовується в наступних позначеннях:

  • \t- Позначає символ табуляції ( t ab)
  • \rі \n- Символи повернення каретки ( r eturn) та нового рядка ( n ew line)
  • \xNN- відповідає символу з ASCII кодом NN, наприклад 41відповідає великої літери A латинського алфавіту
  • \s- відповідає пропуску ( s pace), табуляції, символу нового рядка або символу повернення каретки
  • \d- означає будь-яку цифру ( d igit), а точніше те, що вважається цифрою в Юнікоді (див. слайд номер 102 у цій презентації)
  • \wозначає так зване «слово» ( w ord), аналог

В останніх трьох виразах запис літери в верхньому регістріозначає заперечення. Наприклад, \Dвідповідає виразу [^0-9] , \W- Виразу [^0-9a-zA-Z_], а \S- Будь-якому «не пробельного» символу.

Всі ці «літерні» вирази можна використовувати всередині квадратних дужок. Наприклад, вираз повністю еквівалентно .

На особливу увагу заслуговують висловлювання \bі \B, що означають межу слова (у тому ж розумінні «слова», як і у випадку з \w) та відсутність кордону слова відповідно. Наприклад, виразу perl\bвідповідає рядок "perl rulez!", але не відповідає "perlmonk". З виразом perl\Bвсе з точністю навпаки. Сподіваюся, ідея зрозуміла.

І ще один приклад:

# розбиваємо повне ім'яфайлу на шлях та ім'я
my ($path , $fname ) = $full_name =~ /^(.*)\/([^\/]+)$/ ;

Він ілюструє використання зворотного слеша для екранування символу, який використовується для позначення меж регулярного виразу. У даному прикладіце – прямий слеш.

6. Модифікатори

Поводження регулярних виразів можна змінювати за допомогою модифікаторів. Наприклад, як ви вже могли помітити, відповідність рядка регулярному виразу перевіряється з урахуванням регістру символів. Змінити цю поведінку можна за допомогою модифікатора # (.*?)# g;
# будьте обережні під час використання /g в скалярному контексті
# подробиці тут: http://koorchik.blogspot.com/2011/07/perl-5.html
print "$_ \n " for (@words);

Як було сказано вище, точка позначає будь-який символ, крім символу нового рядка. Змінити таку поведінку можна за допомогою модифікатора /s:

# Видираємо з HTML-файлу вміст статті,
# яке може містити далеко не один і не два рядки
my ($article) = $html =~ m #

(.*?)
#s;

До речі, якщо в регулярному виразі потрібно позначити будь-який символ без використання модифікатора /s, використовуйте вираз [D]. Воно означає «будь-який символ, що є цифрою, або не є цифрою», тобто взагалі будь-який символ.

Зрештою, ніщо не заважає використовувати кілька модифікаторів одночасно:

# Видираємо з HTML-файлу все, що виділено жирним
my @words = $html =~ m # (.*?)#gi;
# спрацює для , або навіть

Додаток:Ще один корисний модифікатор /o. Він означає «компілювати регулярне вираження лише один раз». У деякихвипадках цей модифікатор може суттєво прискорити скрипт. Правда, я не впевнений, що він підтримується десь, окрім Perl. За наведення дякую товаришу

Наведемо кілька прикладів регулярних виразів.

    карова – очевидно, шаблон, під який підходить слово карова;

    \ b (shift | unshift | pop | push | splice) - будь-яке з перерахованих слів;

    ^\s+ - один або кілька прогалин або знаків табуляції, що стоять на початку рядка.

У регулярних виразах алфавітно-цифрові символи зазвичай позначають себе. Наприклад, шаблон Hello вказує шукати символ H , за яким слідує e потім l і т. д.

Якщо символ важко чи незручно поставити буквально, можна використовувати вже відомі нам літерали: \n, \t та інші. Це означає, що знак \ , що входить у регулярне вираз, вже не може позначати сам себе, оскільки він змінює сенс наступного за ним символу: зокрема, літера n разом з попереднім знаком бекслеш позначає символ кінця рядка. Якщо потрібно включити в шаблон знак як такий, слід використовувати літерал \ .

Є й інші символи, які в шаблонах набувають особливого значення замість того, щоб позначати самих себе. Такі символи називаються метасимволами. Наведемо кілька прикладів метасимволів, не вказуючи поки що їх особливий зміст (список не є вичерпним): \.-()()?*+^$| .

Деякі символи виявляються метасимволами який завжди, лише тоді, коли потрапляють у певний контекст. У деяких метасимволів, залежно від контексту, виявляється різний зміст.

Якщо потрібно вставити в регулярне вираз метасимвол, позбавивши його особливого сенсу, його слід захистити ( екранувати), поставивши перед ним бекслеш. Наприклад, знак плюса в регулярне вираз вставляється як \+.

Шаблон позначає один із символів, перерахованих у квадратних дужках. Якщо, наприклад, нас цікавить слово Hello, неважливо, з великої або маленької літери, шаблон буде таким: . Ось шаблон, що означає маленьку голосну літеру англійського алфавіту: . Ще один приклад - символьний клас, що складається з обох квадратних дужок: [\[\]].

Якщо символьний клас включає символи, що йдуть поспіль у кодовій таблиці, достатньо вказати перший і останній символи, Вставивши між ними дефіс. Наприклад, клас, що означає будь-яку десяткову цифру, можна поставити як . Літера англійського алфавіту позначається як (тут ми покладаємося на той факт, що в будь-якій кодовій таблиці великі і малі англійські літерийдуть безперервними блоками в алфавітному порядку; проте блок дрібних букв не слідує відразу за блоком великих).

Можна визначити символьний клас, що складається з усіх символів, за винятком перерахованих - так зване заперечення символьного класу. Для цього відразу за квадратною дужкою перед перерахуванням вставляється знак циркумфлексу ^ . Будь-який символ, який не є цифрою, можна позначити як [^0-9] .

Для деяких популярних класів символів є спеціальні позначення:

У разі успішного зіставлення рядка з регулярним виразом кожному символу або символьному класу у шаблоні відповідає якийсь символ у рядку. Але є конструкції, які позначають наявність певного символу, а певне (порожнє) місце у рядку. Такі конструкції називаються прив'язками, або анкерами

Найчастіше використовувані анкери - прив'язка до початку (^) і до кінця ($) рядка. Прив'язка до початку рядка повинна бути розміщена на початку шаблону, а прив'язка до кінця - в кінці.

Наприклад, до шаблону анти підходять такі слова російської мови, як антидот, антисемітизм або античастка. Без прив'язки також підійшли б рядки, що не починаються з «анти-», але що містять це буквосполучення всередині, наприклад, меркантилізм. Для пошуку слів, що закінчуються на «-тися» потрібен шаблонуватись $ (ми впевнені майже на 100%, що всі такі слова - це зворотні дієслова в інфінітиві). Ніщо не заважає застосовувати в шаблоні обидві ці прив'язки.

Інший корисний анкер - прив'язка до кордону між словами . Він відповідає місцю у рядку, що знаходиться між символами, один з яких належить класу \w, а інший - \W (у будь-якому порядку). Ця прив'язка може відповідати також початку або кінцю рядка (у разі вважається, що терміну оточена уявними символами з класу \W).

Якщо шукаємо фрагмент, який має підійти під одне із кількох шаблонів, потрібно перерахувати ці шаблони, розділивши вертикальної рисою | . Наприклад, понеділок | вівторок | середа | четвер | п'ятниця | субота | неділя. Для того, щоб зробити список альтернатив самостійною одиницею та відокремити від сусідніх, його потрібно укласти у дужки. Наприклад, шаблон Шановний означає рядок Шановний, за яким слідує один з рядковий або інший. Без дужок шаблон Шановний позначав би один з рядків Шановний або я. У дужок є важлива побічна дія, про яку буде сказано в розділі «Угруповання та захоплення» .

Для того щоб вказати, скільки разів може повторюватися шаблон, після нього ставлять так звані квантифікатори(від латинського слова quantum- Скільки):

Квантифікатори *, + і? є надлишковими, оскільки вони можуть бути виражені інакше за допомогою фігурних дужок. А саме, * рівносильний (0,), + рівносильний (1,), а? - те саме, що і (0,1) . Але ці квантифікатори дуже часто використовуються, і цим заслужили окремих позначень.

Якщо шаблон, до якого застосовується квантифікатор, є чимось складнішим, ніж просто одиничний символ або клас символів, його потрібно укласти в круглі дужки.

Ось кілька прикладів:

    ^\d+$ - послідовність з однієї або декількох десяткових цифр (шаблон для цілих невід'ємних чисел у десятковому записі);

    ^\-?\d+$ - те саме, але для всіх (можливо, негативних) цілих чисел;

    ^\-?(\d+(\.\d*)?|\.\d+)$ - шаблон для дійсних чисел;

Розберемо останній приклад докладніше. Крім необов'язкового мінуса на початку, у шаблоні є група з двома альтернативами: \d+(\.\d*)? та \.\d+ . Перша альтернатива включає обов'язкову цілу частину \d+ (як мінімум одна цифра), і наступну необов'язкову дробову (\.\d*)? . У дробовій частині, якщо вона є, є десяткова точка, і, можливо, кілька цифр. Таким чином, цій альтернативі відповідають рядки 15, 15., 15.487. Інша альтернатива потрібна для рядків виду.618 з відсутньою цілою частиною- в багатьох комп'ютерних мовахцей запис має право на існування.

Якщо найпростіші елементи регулярного виразу - символи, символьні класи та анкери, записуються поспіль, це означає, що при пошуку в рядку шаблону ці елементи будуть зіставлятися з частинами рядка послідовно, в тій же послідовності. Цей порядок порушується, якщо використовуються альтернативи. Можна уявляти, що складове регулярне вираз складається з найпростіших за допомогою двох операцій: послідовного з'єднання ( композиції) та альтернативи. Композиція – аналог операції множення в арифметиці. Альтернатива – аналог складання. Перша схожість з арифметикою полягає в тому, що операція альтернативи має нижчий пріоритет, ніж композиція, тому можуть знадобитися дужки для угруповання, як у прикладі Шановний .

Примітка

Багато, хоч і не всі, закони арифметики діють і для регулярних виразів:

комутативність альтернативи x | y = y | x; асоціативність альтернативи x | y | z = x | y | z; асоціативність композиції x ⁣ y ⁣ z = x ⁣ y ⁣ z; дистрибутивність альтернативи щодо композиції (ліва та права) x ⁣ y | z = x ⁣ y | x ⁣ z, x | y ⁣ z = x ⁣ z | y ⁣ z.

У цій дивній арифметиці регулярних виразів немає закону комутативності для композиції. Крім того, відсутній аналог нуля через очевидне співвідношення x | x = x. Роль одиниці (правої та лівої) для композиції виконує порожній шаблон(позначимо його :) : ⁣ x = x ⁣ 𝟙 = x . Квантифікатори виду (n) грають роль зведення в n-ю ступінь.

Крім групувальної функції дужки виконують функцію захоплення. Головним результатом зіставлення рядка із шаблоном є відповідь на запитання: чи підходить рядок під шаблон? Але, крім того, часто буває потрібно визначити, який фрагмент чи фрагменти рядка підійшли до тих чи інших фрагментів у регулярному виразі.

А, можливо, етилендіамін-N N N ' N '-тетраоцтової кислоти?

Розглянемо приклад, у якому тексті знаходяться згадки різних кислот. Наші шкільні спогади з хімії навели нас на думку, що назви кислот закінчуються або на вая, або на ная, або на тая, а потім після пробілу слідує слово кислота. Складаємо шаблон: \S+[внт]ая кислота. Зіставляємо із шаблоном текст. Успіх! Але, питається, згадка якої саме кислоти знайшлась у тексті? Соляний? Сірчаний? Азотної? Плавіковий? Хлорний? Хлорнуватою? Хлорнуватою? Лимонної? Синільною? Дезоксирибонуклеїнової?

Ось тут знадобиться захоплення. Ту частину шаблону, який, за нашим задумом, повинен відповідати назві, укладемо в дужки: (S+[внт]ая) кислота. Тоді машина, знайшовши в тексті згадку про кислоту, збереже її назву (те, що відповідає укладеному в дужки фрагменту шаблону) у спеціальній змінній - буфер захоплення

Регулярний вираз може містити декілька груп захоплення. Такі групи можуть не тільки слідувати одна за одною, а й вкладатися одна в одну. Інакше кажучи, регулярне вираз має бути збалансовано стосовно круглим дужкам у тому сенсі, який обговорювався у розділі 23. « Перевірка балансу дужок»(Звичайно, це стосується тільки круглих дужок, службовців мети угруповання та захоплення; дужки, яким передує бекслеш, не позначаються на балансі груп). При успішному пошуку кожна група захопить якусь частину тексту: перша - до першого буфера, друга - до другого, і так далі. Як же нумеруються групи у разі, коли вони вкладені одна в одну? Нумерація йде в тому порядку, в якому з'являються дужки, що відкривають:

2 4 5 ┝┑ ┝┑┝┑ (()(()())) │ ┝━━━━┙│ │ 3 │ ┝━━━━━━━━┙ 1

За бажання групу можна виключити з нумерації, тобто позбавити її «загарбницької» функції, залишивши лише групуючу. Для цього замість обмежувачів групи (⋯) використовуємо ( ?: ⋯) . Тут знак питання непозначає квантифікатор, оскільки квантифікатор повинні передувати або символ, або символьний клас, або група.

Використання нумерованих груп захоплення не завжди зручне, особливо у великих регулярних виразах. Варто лише вставити у шаблон нову групузахоплення, як нумерація збивається. Тоді доведеться у всіх місцях у програмі, де відбувається звернення до буферів захоплення за номерами, вносити виправлення. Але можна зв'язати з групою ім'я, яке дозволить звернутися до відповідного буфера цього імені. Для створення іменованої групи використовуються обмежувачі ( ? ⋯) , де замість name підставляється потрібне ім'я.

Захоплені в буфери частини рядка можуть бути використані двома шляхами. По-перше, програма, яка використовує регулярний вираз для пошуку або заміни, може звернутися до буферів як до спеціальних змінних. Про це мова йтиметься в розділі «Оператори пошуку та заміни» . Друга можливість передбачає використання посилань на групи прямо в регулярному виразі, див. «Зворотні посилання» .

Розглянемо завдання пошуку слів, що містять три однакові голосні літери поспіль. Наївне рішення [аееіоуэюя](3) , що використовує квантифікатори, не буде працювати, оскільки такому шаблону відповідають рядки з трьома поспіль голосними, але необов'язково однаковими. Жахливе рішення з повним перерахуванням альтернатив, ааа|еее||||ооо|ууу|еээ|ююю|яяяя, ми з обуренням відкидаємо: адже варто взяти інший, більш широкий символьний клас, або замінити трійку в квантифікаторі на більше значення, як розмір шаблону катастрофічно зросте.

Проте можливо елегантне рішеннявикористовує групи захоплення. Захопимо голосну в групу, а потім пошлемося на вміст буфера захоплення. Посилання на перший, другий, третій буфери записуються в регулярному виразі як 1, 2, 3 . Отже, рішенням буде шаблон ([аееіоуэюя])\g1(2) . Зверніть увагу, що посилання на буфер захоплення повинне слідувати в регулярному виразі лише після відповідної групи.

Зворотні посиланняможуть посилатися як на нумеровані буфери, а й іменовані. Такі посилання мають вигляд \k де, знову ж таки, замість name стоїть конкретне ім'я. Наш приклад можна переписати, використовуючи іменовані групи: (? [Аеоіоуеюя]) \ k {2} (vowel- Голосна).

Іноді виникає необхідність у пошуку, при якому не робиться відмінностей між малими та великими літерами. Такий пошук називається нечутливим до регістру (case-insensitive). Замість того, щоб усюди у шаблоні замінювати літери на дволітерні класи (a → , b → , …), просто укласти шаблон в спеціальну групу, Що включає режим case-insensitive пошуку: (? i:⋯) . Така група перестав бути групою захоплення. Якщо case-insensitive пошук має бути реалізований лише у частині регулярного висловлювання, до групи слід помістити лише потрібну частину.

Навпаки, якщо якась частина регулярного виразу, в якій здійснюється case-insensitive пошук, потребує відключення цього режина, то повернутися до звичайного, case-sensitive пошуку можна, використовуючи групу ( ?-i: ⋯) .

Режими чутливості/нечутливості до регістру впливають лише літери. Що вважається буквою, а що ні, залежить від мови, як і правила відповідності між великими та малими літерами. З точки зору англійської мови, наприклад, літерою не є символ Щ. У німецькій мові є буква ß (між іншим, заголовний варіант цієї літери складається з двох літер SS: Carl Friedrich Gauß → CARL FRIEDRICH GAUSS).

Шпаргалка є загальним посібником за шаблонами регулярних виразів без урахування специфіки будь-якої мови. Вона представлена ​​у вигляді таблиці, що міститься на одному друкованому листі формату A4. Створена під ліцензією Creative Commons на базі шпаргалки, автором якої є Dave Child().

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

Якорі в регулярних висловлюваннях вказують на початок чи кінець чогось. Наприклад, рядки чи слова. Вони є певними символами. Наприклад, шаблон, що відповідає рядку, що починається з цифри, повинен мати такий вигляд:

Тут символ ^ означає початок рядка. Без нього шаблон відповідав би будь-якому рядку, що містить цифру.

Символьні класи у регулярних виразах відповідають відразу деякому набору символів. Наприклад, \d відповідає будь-якій цифрі від 0 до 9 включно, \w відповідає буквам і цифрам, а W - всім символам, крім букв і цифр. Шаблон, що ідентифікує літери, цифри та пробіл, виглядає так:

POSIX

POSIX це відносно нове доповнення сімейства регулярних виразів. Ідея, як і у випадку з символьними класами, полягає у використанні скорочень, що становлять певну групу символів.

Спочатку практично у всіх виникають труднощі з розумінням тверджень, проте познайомившись із ними ближче, ви будете використовувати їх досить часто. Твердження надають спосіб сказати: «я хочу знайти в цьому документі кожне слово, що включає букву “q”, за якою не слідує “werty”».

[^\s]*q(?!werty)[^\s]*

Наведений вище код починається з пошуку будь-яких символів, крім пробілу ([^\s]*), за якими слідує q . Потім парсер досягає твердження, що «дивиться вперед». Це автоматично робить попередній елемент (символ, групу або символьний клас) умовним - він буде відповідати шаблону, тільки якщо твердження правильне. У нашому випадку, твердження є негативним (?!), Тобто воно буде вірним, якщо те, що в ньому шукається, не буде знайдено.

Отже, парсер перевіряє кілька таких символів за запропонованим шаблоном (werty). Якщо вони знайдені, то твердження хибне, а значить символ q буде «проігнорований», тобто не відповідатиме шаблону. Якщо ж werty не знайдено, то твердження вірне, і з q все гаразд. Потім продовжується пошук будь-яких символів, крім пропуску ([^\s]*).

У цій групі представлені зразки шаблонів. З їхньою допомогою ви можете побачити, як можна використовувати регулярні вирази у щоденній практиці. Однак зауважте, що вони не обов'язково працюватимуть у будь-якій мові програмування, оскільки кожен з них має індивідуальними особливостямита різним рівнем підтримки регулярних виразів.

Квантори дозволяють визначити частину шаблону, яка має повторюватися кілька разів поспіль. Наприклад, якщо ви хочете з'ясувати, чи містить документ рядок від 10 до 20 (включно) букв «a», то можна використовувати цей шаблон:

A(10,20)

За замовчуванням квантори – «жадібні». Тому квантор + , що означає «один або більше разів», відповідатиме максимально можливому значенню. Іноді це викликає проблеми, і тоді ви можете сказати квантор перестати бути жадібним (стати «лінивим»), використовуючи спеціальний модифікатор. Подивіться цей код:

".*"

Цей шаблон відповідає тексту, укладеному в подвійні лапки. Однак, ваш вихідний рядок може бути на кшталт цього:

Привіт світ

Наведений вище шаблон знайде в цьому рядку такий підрядок:

"helloworld.htm" title="Привіт, Світ" !}

Він виявився надто жадібним, захопивши найбільший шмат тексту, який зміг.

".*?"

Цей шаблон також відповідає будь-яким символам, укладеним у подвійні лапки. Але лінива версія (зверніть увагу на модифікатор?) шукає найменше з можливих входжень, і тому знайде кожну підрядку в подвійних лапкахокремо:

"helloworld.htm" "Привіт, Світ"

Регулярні вирази використовують деякі символи для позначення різних частин шаблону. Однак, виникає проблема, якщо вам потрібно знайти один із таких символів у рядку, як звичайний символ. Крапка, наприклад, у регулярному вираженні означає «будь-який символ, крім перенесення рядка». Якщо потрібно знайти точку в рядку, ви не можете просто використовувати « . » як шаблон - це призведе до знаходження практично всього. Отже, вам необхідно повідомити парсера, що ця точка повинна вважатися звичайною точкою, а не будь-яким символом. Це робиться за допомогою значка екранування.

Знак екранування, який передує символу на кшталт точки, змушує парсер ігнорувати його функцію і вважати звичайним символом. Є кілька символів, які потребують такого екранування у більшості шаблонів та мов. Ви можете знайти їх у правому нижньому кутку шпаргалки («Мета-символи»).

Шаблон для знаходження точки такий:

\.

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

Підстановка рядків докладно описана в наступному параграфі "Групи та діапазони", проте тут слід згадати про існування "пасивних" груп. Це групи, що ігноруються при підстановці, що дуже корисно, якщо ви хочете використовувати в шаблоні умову «або», але не хочете, щоб ця група брала участь у підстановці.

Групи та діапазони дуже-дуже корисні. Ймовірно, простіше розпочатиме з діапазонів. Вони дозволяють вказати набір відповідних символів. Наприклад, щоб перевірити, чи містить рядок шістнадцяткові цифри (від 0 до 9 і від A до F), слід використовувати такий діапазон:

Щоб перевірити зворотне, використовуйте негативний діапазон, який у нашому випадку підходить під будь-який символ, крім цифр від 0 до 9 та літер від A до F:

[^A-Fa-f0-9]

Групи найчастіше застосовуються, як у шаблоні необхідна умова «або»; коли потрібно послатися на частину шаблону з іншої частини; а також при підстановці рядків.

Використовувати "або" дуже просто: наступний шаблон шукає "ab" або "bc":

Якщо в регулярному виразі необхідно послатися на якусь із попередніх груп, слід використовувати \n , де замість n підставити номер потрібної групи. Вам може знадобитися шаблон, що відповідає літерам «aaa» або «bbb», за якими слідує число, а потім ті ж три літери. Такий шаблон реалізується за допомогою груп:

(aaa|bbb)+\1

Перша частина шаблону шукає "aaa" або "bbb", поєднуючи знайдені літери в групу. За цим слідує пошук однієї або більше цифр (+), і нарешті \1. Остання частина шаблону посилається на першу групу і шукає те саме. Вона шукає збіг з текстом, вже знайденим першою частиною шаблону, а чи не відповідний йому. Таким чином, «aaa123bbb» не задовольнятиме вищенаведений шаблон, оскільки \1 шукатиме «aaa» після числа.

Одним з найбільш корисних інструментіву регулярних виразах є підстановка рядків. При заміні тексту можна послатися на знайдену групу за допомогою $n . Скажімо, ви хочете виділити у тексті всі слова «wish» жирним зображенням. Для цього вам слід використовувати функцію заміни за регулярним виразом, яка може виглядати так:

Replace(pattern, replacement, subject)

Першим параметром буде приблизно такий шаблон (можливо вам знадобляться кілька додаткових символів для цієї конкретної функції):

([^A-Za-z0-9])(wish)([^A-Za-z0-9])

Він знайде будь-які входження слова wish разом з попереднім і наступним символами, якщо це не літери чи цифри. Тоді ваша підстановка може бути такою:

$1$2$3

Нею буде замінено весь знайдений за шаблоном рядок. Ми починаємо заміну з першого знайденого символу (який не буква і цифра), відзначаючи його $1 . Без цього ми просто видалили б цей символ з тексту. Те саме стосується кінця підстановки ($3). У середину ми додали HTML тегдля жирного зображення (зрозуміло, замість нього ви можете використовувати CSS або ), виділивши їм другу групу, знайдену за шаблоном ($2).

Модифікатори шаблонів використовуються кількома мовами, зокрема Perl. Вони дозволяють змінити роботу парсера. Наприклад, модифікатор i змушує парсер ігнорувати регістри.

Регулярні вирази в Perl обрамляються одним і тим самим символом на початку та наприкінці. Це може бути будь-який символ (частіше використовується «/»), і виглядає так:

/pattern/

Модифікатори додаються до кінця цього рядка, ось так:

/pattern/i

Нарешті, остання частина таблиці містить мета-символи. Це символи, що мають спеціальне значення у регулярних виразах. Так що якщо ви хочете використовувати один з них як звичайний символ, його необхідно екранувати. Для перевірки наявності дужки в тексті використовується такий шаблон:

Реально дякую. особливо через роз'яснення. Це будь ласка:) велике спасибі. дякую величезне вам! Дякую Класна серія... я до речі перекладаю з англійської цю серію (і роблю в HTML форматі), у мене на сайті можете переглянути: sitemaker.x10.bz. Там є і шпаргалка з HTML, якої тут немає. Дякую. А як на рахунок прибрати перші 10 символів будь-яких і потім буде якийсь текст із символами, і далі з певного символутреба буде прибрати все до кінця. !? 2 lails: Тут регулярні вирази не потрібні. Вам допоможуть substr() і strpos(), якщо мова про PHP, або їх аналоги іншими мовами. Цікаво було про твердження почитати, понеможу починаю розуміти. Ось так наочніше буде: Здрастуйте. Підкажіть будь ласка - чому у мене в FireFox не працюють "затвердження, що дивляться назад"? У довідці RegExp Мозили їх взагалі немає, невже в Лисі це неможливо? =(((( Доброго ранку, що дивляться назад твердження не підтримуються JavaScript"ом, тому в інших браузерах, ймовірно, теж не будуть працювати. За цим посиланням є більше Детальна інформаціяпро обмеження регулярок у мові JavaScript. Молодця! давай п'ятю! Дякую! Коротко та наочно! Хм. Пасиба) Дякую! дякую, дуже допомогло спасибі велике! Дякую за статтю! Підкажіть, а якщо потрібно обмежити введення пароля цифрами та введенням не більше 5 літер? Здрастуйте, шпаргалка всім хороша, але можна було б зробити зебру світлішою, бо коли друкуєш чорні літери на темному тліне дуже Дякую. Невелике питання потрібно знайти значення між start= і &, але при цьому виключити дані межі діапазону з видачі. Як знайти діапазон зробив: start=.(1,)&
А ось як виключити кордони, знань поки що не вистачає. Буду вдячний за допомогу. Підкажіть, будь ласка, як задати регулярний вираз на перевірку (може бути, а може і не бути збіг)? Як правильно записати регулярку починається зі знака рівно, знаходить будь-який текст усередині та зупиняється на знаку &
Ці знаки не включені в пошук з них починається та закінчується потрібна частинарядки...

Пишу кількома способами, але в результаті залишається весь текст, але зникають знаки = і &
Або залишається знак & в кінці рядка...
Читав про долар він не видаляє символ у кінці рядка

невеликий приклад

var reg = /[^=]*[^&]/g
str.match(reg);

За логікою ми починаємо зі знаку рівності та шукаємо будь-який текст /[^=]*
далі зупиняємося на знаку & [^&] не включаючи його в пошук і повторюємо пошук довше, поки не обійдемо його повністю / g

Не працює... Повертає повністю рядок

Доброго вечора, підкажіть, як знайти число, яке менше 20? Дякую хлопці Дякую за статтю! Підкажіть, а якщо потрібно обмежити введення пароля цифрами та введенням не більше 5 літер?

Діма @ 24 квітня 2015
Відповідь:((?=.*\d)(?=.*)(?=.*).(8,15))--- в кінці замість 8 просто поставте 5

Всім привіт, я починаю тільки...
Не могли б ви мені підказати, що означає:
/^\w\w/a
Буду дуже вдячний) Здрастуйте, підкажіть як перерахуйте всі цифри в даному вираженнічерез пропуск 9*2 Божественна шпаргалка! Зняла всі питання:-) (M1)
(M2)
(M3)
(M4)
(M5)

Підкажіть як написати вираз, щоб знайти де зустрічається в тексті