Відповіді:
Найважливіша частина - це поняття. Як тільки ви зрозумієте, як працюють будівельні блоки, відмінності в синтаксисі становлять трохи більше, ніж легкі діалекти. Шар, що знаходиться над синтаксисом двигуна регулярного виразу, є синтаксисом мови програмування, яку ви використовуєте. Такі мови, як Perl, усувають більшу частину цього ускладнення, але вам доведеться пам’ятати про інші міркування, якщо ви використовуєте регулярні вирази в програмі C.
Якщо ви вважаєте, що регулярні вирази є будівельними блоками, які ви можете змішувати та співставляти за своїм бажанням, це допоможе вам навчитися писати та налагоджувати власні шаблони, а також як зрозуміти шаблони, написані іншими.
Концептуально найпростіші регулярні вирази - це буквальні символи. Шаблон Nвідповідає символу "N".
Регулярні вирази поруч один з одним відповідають послідовностям. Наприклад, шаблон Nickвідповідає послідовності 'N', а потім 'i', а потім 'c' і 'k'.
Якщо ви коли-небудь використовували grepв Unix - навіть якщо тільки шукати звичайні вигляд рядків - ви вже використовували регулярні вирази! (The reв grepставиться до регулярних виразах.)
Додавши лише невелику складність, ви можете зрівняти «Нік» або «Нік» з малюнком [Nn]ick. Частина у квадратних дужках є класом символів , а це означає, що вона відповідає точно одному з доданих символів. Ви також можете використовувати діапазони в класах символів, так що [a-c]відповідає "a" або "b" або "c".
Шаблон .особливий: замість того, щоб відповідати лише буквальній крапці, він відповідає будь-якому символу † . Це те саме концептуально, як і справді великий клас персонажів [-.?+%$A-Za-z0-9...].
Подумайте про класи персонажів як меню: виберіть лише один.
Використання .дозволяє заощадити багато тексту, а також є інші ярлики для поширених шаблонів. Скажіть, що ви хочете зіставити цифру: один із способів написати це [0-9]. Цифри є частою ціллю відповідності, тому ви можете замість цього використовувати ярлик \d. Інші - це \s(пробіли) та \w(символи слова: буквено-цифрові чи підкреслення).
Варіанти верхнього розміру є їх доповненнями, тому \Sвідповідають будь- якому символу, що не є простором, наприклад.
Звідти ви можете повторити частини свого візерунка за допомогою кількісних показників . Наприклад, шаблон ab?cвідповідає "abc" або "ac", оскільки ?кількісний показник робить підпакет, який він модифікує необов'язково. Інші кількісні показники є
* (нуль або більше разів)+ (один або кілька разів){n}(рівно n разів){n,}(принаймні n разів){n,m}(принаймні n разів, але не більше m разів)Збираючи деякі з цих блоків разом, шаблон [Nn]*ickвідповідає всім
Перший матч демонструє важливе заняття: *завжди вдається! Будь-яка модель може відповідати нулю разів.
Ще кілька корисних прикладів:
[0-9]+(і його еквівалент \d+) відповідає будь-якому цілому, що не має негативного значення\d{4}-\d{2}-\d{2} Дати матчів відформатовані як 01.01.2019Кількісний показник змінює шаблон вліво зліва. Ви можете розраховувати 0abc+0на відповідність "0abc0", "0abcabc0" тощо, але одразу зліва від кількісного показника плюс є c. Це означає, що 0abc+0відповідає '0abc0', '0abcc0', '0abccc0' тощо.
Щоб співставити одну або кілька послідовностей 'abc' з нулями на кінцях, використовуйте 0(abc)+0. В дужках позначають підтермін, який можна кількісно визначити як одиницю. Для двигунів регулярного вираження також часто зберігається або "захоплюється" частина вхідного тексту, що відповідає груповій групі. Цей спосіб вилучення бітів набагато гнучкіший і менш схильний до помилок, ніж підрахунок індексів і substr.
Раніше ми бачили один із способів зіставити "Нік" або "Нік". Інша - з чергуванням, як у Nick|nick. Пам'ятайте, що чергування включає все зліва і все праворуч. Використання групування дужки для обмеження обсягу |, наприклад , (Nick|nick).
В іншому прикладі ви можете еквівалентно записати [a-c]як a|b|c, але це, ймовірно, буде неоптимальним, оскільки багато реалізацій припускають, що альтернативи матимуть довжину більше 1.
Хоча одні персонажі відповідають собі, інші мають особливі значення. Шаблон \d+не відповідає зворотній косої риси, за якою слідує нижній регістр D, а потім знак плюс: щоб отримати це, ми використали б \\d\+. Зворотна косою рисою видаляє спеціальне значення з наступного символу.
Кількісні показники регулярного вираження жадібні. Це означає, що вони відповідають стільки тексту, скільки можливо, дозволяючи успішно співставити весь шаблон.
Наприклад, скажімо, вхід є
- Привіт, - сказала вона, - як справи?
Ви можете розраховувати, ".+"що відповідатиме лише "Привіт", а потім будете здивовані, коли побачите, що він відповідає "Привіт" весь шлях через "ви?".
Щоб переключитися з жадібного на те, що ви можете вважати обережним, додайте додатковий ?квантор. Тепер ви зрозуміли, як \((.+?)\)працює приклад із вашого запитання. Він відповідає послідовності буквальної лівої дужки, за якою слідує один або кілька символів, і закінчується правою дужкою.
Якщо ваш вхід '(123) (456)', то першим захопленням буде '123'. Не жадібні квантори бажають дозволити решті шаблону почати відповідність якомога швидше.
(Що стосується вашої плутанини, я не знаю жодного діалекту з регулярними виразами, де ((.+?))було б те саме. Я підозрюю, що щось загубилося в передачі десь по дорозі.)
Використовуйте спеціальний зразок, ^щоб відповідати лише на початку введення даних та $відповідати лише в кінці. Зробити "підписки" за своїми візерунками, де ви говорите: "Я знаю, що спереду і ззаду, але дайте мені все між" - корисна техніка.
Скажіть, ви хочете відповідати коментарям форми
-- This is a comment --
ти напишеш ^--\s+(.+)\s+--$.
Регулярні вирази є рекурсивними, тому тепер, коли ви розумієте ці основні правила, ви можете комбінувати їх, як завгодно.
†: Наведене вище твердження про те, що .відповідає будь-якому персонажу, є спрощенням у педагогічних цілях, що не є суто правдивим. Точка відповідає будь-якому символу, окрім нового рядка, "\n"але на практиці ви рідко очікуєте такого шаблону, як .+перетинати межу нового рядка. Регекси Perl мають /sперемикач і Java Pattern.DOTALL, наприклад, щоб .взагалі відповідати будь-якому символу. Для мов, які не мають такої функції, ви можете використовувати щось на зразок, [\s\S]щоб відповідати "будь-якому пробілу чи будь-якому простору", тобто будь-що.
a{,m}це не річ, принаймні у Javascript, Perl та Python.