Навчання регулярним виразам [закрито]


166

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

Відповіді:


789

Найважливіша частина - це поняття. Як тільки ви зрозумієте, як працюють будівельні блоки, відмінності в синтаксисі становлять трохи більше, ніж легкі діалекти. Шар, що знаходиться над синтаксисом двигуна регулярного виразу, є синтаксисом мови програмування, яку ви використовуєте. Такі мови, як 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відповідає всім

  • ритм
  • Нік
  • нік
  • Nnick
  • nNick
  • нік
  • (і так далі)

Перший матч демонструє важливе заняття: *завжди вдається! Будь-яка модель може відповідати нулю разів.

Ще кілька корисних прикладів:

  • [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]щоб відповідати "будь-якому пробілу чи будь-якому простору", тобто будь-що.


14
Ви також можете скористатись методом проб і помилок, і чим слідкувати за тестером та відладкою
Juraj.Lorinc

2
Варто зазначити, що, незважаючи на подібний зразок, a{,m}це не річ, принаймні у Javascript, Perl та Python.
Фонд позову Моніки

2
Було б дуже важливо відзначити, що існують різні види двигунів регулярного вираження, які мають різні набори функцій та синтаксичні правила.
hek2mgl

1
hackr.io/tutorials/learn-regular-expressions-regex - це прекрасне місце для пошуку найкращих онлайн-підручників з регексу . Всі навчальні посібники тут подаються та рекомендуються (рекомендуються як SO) програмною спільнотою.
Saurabh Hooda

2
Вдячні за ваші зусилля, щоб все це було сюди вкрай.
Саурабх Тіварі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.