Шпаргалка за регулярними виразами PERL

По темі:


Глава 6.4. Регулярні вирази

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

Регулярні вислови є зразки для пошуку заданих комбінацій символів в текстових рядках і заміни їх на інші комбінації символів (ці операції називаються відповідно зіставлення зі зразком і підстановка). Регулярний вираз в мові PERL має вигляд

  / Pattern / modifiers 

Тут pattern - це рядок, що задає регулярний вираз, а modifiers - необов'язкові однобуквені модифікатори , уточнюючі правила використання цього регулярного виразу.

Регулярний вираз може складатися зі звичайних символів; в цьому випадку воно буде відповідати заданій комбінації символів в рядку. Наприклад, вираз / кат / відповідає виділеним підрядками в наступних рядках: "кат ок", "за кат",кат ить". Однак, справжню силу регулярними виразами PERLа надає можливість використання в них спеціальних метасимволов.

Таблиця 6.9. Метасимволи в регулярних виразах
символ опис
\ Для символів, які зазвичай трактуються буквально, означає, що наступний символ є метасимволом. Наприклад, / n / відповідає букві n, а / \ n / відповідає символу перекладу рядка.
Для метасимволов означає, що символ повинен розумітися буквально. Наприклад, / ^ / означає початок рядка, а / \ ^ / відповідає просто символу ^. / \\ / Відповідає зворотної косої межі \.
^ Відповідає початку рядка (пор. Модифікатор m ).
$ Відповідає кінця рядка (пор. Модифікатор m ).
. Відповідає будь-якому символу, крім розриву рядка (пор. Модифікатор s ).
* Відповідає повторення попереднього символу нуль або більше разів.
+ Відповідає повторення попереднього символу один або більше разів.
? Відповідає повторення попереднього символу нуль або один раз.
(Pattern) Відповідає рядку pattern і запам'ятовує знайдене відповідність .
x | y Відповідає x або y.
{N} n - невід'ємне число. Відповідає рівно n входженням попереднього символу.
{N,} n - невід'ємне число. Відповідає n або більше входженням попереднього символу. / X {1,} / еквівалентно / x + /. / X {0,} / еквівалентно / x * /.
{N, m} n і m - невід'ємні числа. Відповідає не менше ніж n і не більше ніж m входженням попереднього символу. / X {0,1} / еквівалентно / x? /.
[Xyz] Відповідає будь-якому символу з ув'язнених в квадратні дужки.
[^ Xyz] Відповідає будь-якому символу, крім вкладених у квадратні дужки.
[A - z] Відповідає будь-якому символу у вказаному діапазоні.
[^ A - z] Відповідає будь-якому символу, крім лежать в зазначеному діапазоні.
\ a Відповідає символу дзвінок (BEL).
\ A Відповідає тільки початок рядка, навіть з модифікатором m .
\ b Відповідає кордоні слова, т. Е. Позиції між \ w і \ W в будь-якому порядку.
\ B Відповідає будь-якій позиції, окрім кордону слова.
\ с X Відповідає символу Ctrl + X. Наприклад, / \ cI / еквівалентно / \ t /.
\ C Відповідає одному байту, навіть при директиві use utf8.
\ d Відповідає цифрі. Еквівалентно [0-9].
\ D Відповідає нецифровому символу. Еквівалентно [^ 0-9].
\ e Відповідає символу escape (ESC).
\ E Кінець перетворень \ L, \ Q, \ U.
\ f Відповідає символу перекладу формату (FF).
\ G Відповідає позиції в рядку, що дорівнює pos ().
\ l Перетворює наступний символ в нижній регістр.
\ L Перетворює символи в нижній регістр до \ E.
\ n Відповідає розриву рядків.
\ p property Відповідає символам Unicode, що володіє властивістю property. Якщо property задається кількома символами, використовуйте синтаксис \ p {property}.
\ P property Відповідає символам Unicode, що не володіє властивістю property. Якщо property задається кількома символами, використовуйте синтаксис \ P {property}.
\ Q Додає символ "\" перед метасимвол до \ E.
\ r Відповідає символу повернення каретки (CR).
\ s Відповідає символу пробілу. Еквівалентно / [\ f \ n \ r \ t] /.
\ S Відповідає будь-якому непробельний символу. Еквівалентно / [^ \ f \ n \ r \ t] /.
\ t Відповідає символу табуляції (HT).
\ u Перетворює наступний символ у верхній регістр.
\ U Перетворює символи у верхній регістр до \ E.
\ w Відповідає латинської букви, цифри або підкреслення. Еквівалентно / [A-Za-z0-9_] /.
\ W Відповідає будь-якому символу, крім латинської букви, цифри або підкреслення. Еквівалентно / [^ A-Za-z0-9_] /.
\ X Відповідає послідовності символів Unicode з основного символу і набору діакритичних значків. Еквівалентно висловом / C <(?: \ PM \ pM *)> /.
\ z Відповідає тільки кінця рядка, навіть з модифікатором m .
\ Z Відповідає тільки кінця рядка або розриву рядків в кінці рядка, навіть з модифікатором m .
\ n n - позитивне число. Відповідає n -ї запомненной підрядку . Якщо лівих дужок до цього символу менше, ніж n, і n> 9, то еквівалентно \ 0 n.
\ 0 n n - вісімкове число, не більше 377. Відповідає символу з восьмеричним кодом n. Наприклад, / \ 011 / еквівалентно / \ t /.
\ x n n - шістнадцяткове число, що складається з двох цифр. Відповідає символу з шістнадцятковим кодом n. Наприклад, / \ x31 / еквівалентно / 1 /.
\ x {n} n - шістнадцяткове число, що складається з чотирьох цифр. Відповідає символу Unicode з шістнадцятковим кодом n. Наприклад, / \ x {2663} / еквівалентно / ♣ /.

6.4.2. модифікатори

Різні операції з регулярними виразами використовують різні модифікатори для уточнення виконуваної операції. Однак, чотири модифікатора мають загальне призначення.

i
Ігнорує регістр символів при зіставленні зі зразком. При використанні директиви use locale приведення символів до одного регістру проводиться з урахуванням національної настройки.
m
Розглядає вихідну рядок як буфер з кількох рядків тексту, розділених розривами рядків. Це означає, що метасимволу ^ і $ відповідають не тільки початку і кінця всього рядка, але і початку і кінця рядку тексту, обмеженою розривами рядків.
s
Розглядає вихідну рядок як єдиний рядок тексту, ігноруючи розриви рядків. Це означає, що метасимвол. відповідає будь-якому символу, включаючи розрив рядка.
x
Дозволяє використання прогалин і коментарів. Прогалини, які не мають попереднього символу \ і не укладені в [], ігноруються. Символ # починає коментар, який також ігнорується.

6.4.3. Класи символів Unicode і POSIX

Ми можемо використовувати в регулярних виразах синтаксис

  [: Class:] 

де class задає назву класу символів POSIX, т. е. мобільного стандарту на мову C. При використанні директиви use utf8 замість класів POSIX можна використовувати класи символів Unicode в конструкції

  \ P {class} 

В наступній таблиці зведені всі класи символів POSIX, відповідні класи символів Unicode і метасимволу, якщо вони є.

Таблиця 6.10. класи символів
POSIX Unicode метасимвол опис
alpha IsAlpha букви
alnum IsAlnum Букви і цифри
ascii IsAscii символи ASCII
cntrl IsCntrl керуючі символи
digit IsDigit \ d цифри
graph IsGraph Букви, цифри і знаки пунктуації
lower IsLower малі літери
print IsPrint Букви, цифри, знаки пунктуації та пробіл
punct IsPunct знаки пунктуації
space IsSpace \ s символи пробілу
upper IsUpper Прописні літери
word IsWord \ w Букви, цифри і підкреслення
xdigit IsXDigit шістнадцятиричні цифри

Наприклад, десяткове число можна задати будь-яким з наступних трьох способів:

  / \ D + /
 / [: Digit:] + /
 / \ P {IsDigit} + / # use utf8 

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

  [: ^ Class:]
 \ P {class}

Наприклад, такі вирази мають однаковий сенс:

  [: ^ Digit:] \ D \ P {IsDigit}
 [: ^ Space:] \ S \ P {IsSpace}
 [: ^ Word:] \ W \ P {IsWord} 

6.4.4. запам'ятовування подстрок

Використання круглих дужок в регулярному виразі приводить до того, що подстрока, відповідна зразком в дужках, запам'ятовується в буфері. Для доступу до n -ї запомненной підрядку всередині регулярного виразу використовується конструкція \ n, а поза ним - $ n, де n може приймати будь-які значення, починаючи з 1. Однак, слід пам'ятати, що PERL використовує вирази \ 10, \ 11 і т . д. як синоніми для вісімкових кодів символів \ 010, \ 011 і т. д. Неоднозначність тут дозволяється так. Символ \ 10 вважається зверненням до 10-ї запомненной підрядку, якщо перед ним в регулярному виразі коштує не менше десяти лівих круглих дужок; в іншому випадку, це символ з восьмеричним кодом 10. Метасимволи \ 1, ... \ 9 завжди вважаються зверненнями до запомненним підрядками. приклади:

  if (/(.)\1/) {# шукаємо перший повторюється символ
  print " '$ 1' - перший повторюється символ \ n";
 }
 if (/ Time: (..) :( ..) :( ..) /) {# Витягаємо компоненти часу
  $ Hours = $ 1;
  $ Minutes = $ 2;
  $ Seconds = $ 3;
 } 

Крім змінних $ 1, $ 2, ... є ще кілька спеціальних змінних, в яких зберігаються результати останньої операції з регулярним виразом, а саме:

Мінлива опис
$ & Остання знайдений підрядок.
$ ` Підрядок перед останньою знайденою підрядком.
$ ' Підрядок після останньої знайденої підрядка.
$ + Остання після успішної реєстрації подстрока.

Наведемо приклад:

  'AAA111BBB222' = ~ / (\ d +) /;
 print "$` \ n ";  # AAA
 print "$ & \ n";  # 111
 print "$ '\ n";  # BBB222
 print "$ + \ n";  # 111 

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

6.4.5. розширені зразки

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

(? # Text)
Коментар. Вся конструкція ігнорується.
(? Modifiers - modifiers)
Вмикає або вимикає задані модифікатори . Модифікатори, які стоять до символу -, включаються, які стоять після нього - вимикаються. приклад:
  if (/ aaa /) {...} # зіставлення з урахуванням регістру
 if (/ (? i) aaa /) {...} # зіставлення без урахування регістру 
(?: Pattern)
(? Modifiers - modifiers: pattern)
Дозволяє групувати подвираженія регулярного виразу без запам'ятовування знайденого відповідності. Друга форма додатково включає або вимикає задані модифікатори . Наприклад, вираз /ко(?:т|шка)/ - це короткий запис вираження /кот|кошка/ .
(? = Pattern)
Відповідність з загляданням вперед без запам'ятовування знайденого відповідності. Наприклад, вираз /Windows (?=95|98|NT|2000)/ відповідає "Windows" в рядку "Windows 98", але не відповідає в рядку "Windows 3.1". Після зіставлення пошук триває з позиції, наступної за знайденим відповідністю, без урахування заглядання вперед.
(?! Pattern)
Невідповідність з загляданням вперед без запам'ятовування знайденого відповідності. Наприклад, вираз /Windows (?!95|98|NT|2000)/ відповідає "Windows" в рядку "Windows 3.1", але не відповідає в рядку "Windows 98". Після зіставлення пошук триває з позиції, наступної за знайденим відповідністю, без урахування заглядання вперед.
(? <= Pattern)
Відповідність з загляданням назад без запам'ятовування знайденого відповідності. Наприклад, вираз /(?<=\t)\w+/ відповідає слову, наступного за символом табуляції, а також табуляцію не включається в $ &. Фрагмент, відповідний заглядання назад, повинен мати фіксовану ширину.
(? <! Pattern)
Невідповідність з загляданням назад без запам'ятовування знайденого відповідності. Наприклад, вираз /(?<!\t)\w+/ відповідає слову, перед яким немає символу табуляції. Фрагмент, відповідний заглядання назад, повинен мати фіксовану ширину.

6.4.6. Операції з регулярними виразами

До сих пір ми укладали регулярні вирази в символи //. Насправді символи-обмежувачі регулярного виразу визначаються q-операцією , яку ми до них застосовуємо. У цьому розділі докладно описані всі операції мови PERL з регулярними виразами.

6.4.6.1. Зіставлення зі зразком

  Синтаксис: / pattern / modifiers m / pattern / modifiers
 

Ця операція зіставляє задану рядок зі зразком pattern і повертає істину або брехня в залежності від результату зіставлення. Зіставляється рядок задається лівим операндом операції = ~ або! ~, Наприклад:

  $ Mynumber = '12345';
 if ($ mynumber = ~ / ^ \ d + $ /) {# якщо рядок $ mynumber складається з десяткових цифр, то ...
  ...
 } 

Якщо рядок не задана, то проводиться зіставлення з вмістом спеціальної змінної $ _. Зокрема, попередній приклад можна переписати так:

  $ _ = '12345';
 if (/ ^ \ d + $ /) {
  ...
 } 

Крім стандартних, тут можна використовувати такі модифікатори:

модифікатор опис
c Чи не скидати позицію пошуку при невдалому зіставленні (тільки з модифікатором g).
g Глобальне зіставлення, т. Е. Пошук всіх входжень зразка.
o Компілювати регулярний вираз тільки один раз.

Якщо регулярний вираз укладено в //, то початкове m необов'язково. Конструкція з початковим m дозволяє використовувати в якості обмежувачів регулярного виразу будь-які символи, допустимі в q-операціях. Корисні окремі випадки:

  • Якщо обмежувачами є символи '', то інтерполяція рядка pattern не проводиться. В інших випадках відбувається інтерпретація зразка і якщо він містить змінні, то при кожному зіставленні проводиться його компіляція. Щоб уникнути цього, використовуйте модифікатор o (зрозуміло, якщо ви впевнені, що значення змінних, що входять в зразок, залишаються незмінними).
  • Якщо обмежувачами є символи ?? , То застосовується правило єдиного зіставлення .

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

Якщо не заданий модифікатор g і результат зіставлення присвоюється списку, то при невдалому зіставленні повертається порожній список. Результат вдалого зіставлення залежить від наявності круглих дужок в зразку. Якщо їх немає, то повертається список (1). В іншому випадку повертається список, що складається з значень змінних $ 1, $ 2 і т. Д., Т. Е. Список всіх запам'ятали подстрок. наступний приклад

  ($ W1, $ w2, $ rest) = ($ x = ~ /^(\S+)\s+(\S+)\s*(.*)/); 

заносить в змінну $ w1 перше слово рядка $ x, в змінну $ w2 її друге слово, а в змінну $ rest - залишок цього рядка.

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

  $ _ = "12:23:45";
 @result = / \ d + / g;
 foreach $ elem (@result) {
  print "$ elem \ n";
 } 

виведе на екран рядка 12, 23 і 45.

У скалярному контексті зіставлення з модифікатором g кожен раз шукає наступне відповідність зразком і повертає істину або брехня в залежності від результату пошуку. Позиція в рядку після останнього зіставлення може бути зчитана або змінена функцією pos (). Невдалий пошук зазвичай скидає позицію пошуку в нуль, але ми можемо уникнути цього, додавши модифікатор c. Зміна рядка також призводить до скидання позиції пошуку в ній.

Додаткові можливості надає метасимвол \ G, який має сенс тільки в поєднанні з модифікатором g. Цей метасимвол відповідає поточній позиції пошуку в рядку. Використання конструкції m / \ G ... / gc зручно, зокрема, для написання лексичних аналізаторів, що виконують різні дії для зустрінутих в уже згадуваному тексті лексем. наступний приклад

  $ _ = 'Word1, word2, and 12345.';
 LOOP:
  {
  print ( "number"), redo LOOP if /\G\d+\b[,.;]?\s*/gc;
  print ( "word"), redo LOOP if /\G[A-Za-z0-9]+\b[,.;]?\s*/gc;
  print ( "unknown"), redo LOOP if / \ G [^ A-Za-z0-9] + / gc;
  } 

виведе на екран рядок word word word number.

6.4.6.2. Єдине зіставлення зі зразком

  Синтаксис:?
  pattern?

  m?  pattern?
 

Ця конструкція повністю аналогічна конструкції m / pattern / с єдиною відмінністю: успішне зіставлення зі зразком виконується тільки один раз між викликами функції reset () . Це зручно, наприклад, коли нам потрібно знайти тільки перше входження зразка в кожному файлі з проглядається набору, наприклад:

  while (<>) {
  if (? ^ $?) {
  ... # Обробити перший пустий рядок файлу
  }
 } Continue {
  reset if eof;  # Скинути статус ??  для наступного файлу
 } 

6.4.6.3. Створення регулярного виразу

  Синтаксис: qr / string / modifiers
 

Ця конструкція створює регулярний вираз з текстом string і модифікаторами modifiers і компілює його. Якщо обмежувачами є символи '', то інтерполяція рядка string не проводиться. В інших випадках відбувається інтерпретація зразка і якщо він містить змінні, то при кожному зіставленні проводиться його компіляція. Щоб уникнути цього, використовуйте модифікатор o (зрозуміло, якщо ви впевнені, що значення змінних, що входять в зразок, залишаються незмінними).

Одного разу створене регулярне вираз може вживатися як самостійно, так і в якості фрагмента інших регулярних виразів. приклади:

  $ Re = qr / \ d + /;
 $ String = ~ / \ s * $ {re} \ s * /;  # Включення в інше регулярний вираз
 $ String = ~ $ re;  # Самостійне використання
 $ String = ~ / $ re /;  # теж саме

 $ Re = qr / $ header / is;
 s / $ re / text /;  # Те саме, що s / $ header / text / is 

6.4.6.4. підстановка

  Синтаксис: s / pattern / string / modifiers
 

Ця операція зіставляє задану рядок зі зразком pattern і замінює знайдені фрагменти на рядок string. Вона повертає кількість проведених замін або брехня (точніше, порожній рядок), якщо зіставлення закінчилося невдачею. Зіставляється рядок задається лівим операндом операції = ~ або! ~. Вона повинна бути скалярної змінної, елементом масиву або елементом асоціативного масиву, наприклад:

  $ Path = '/ usr / bin / perl';
 $ Path = ~ s | / usr / bin | / usr / local / bin |; 

Якщо рядок не задана, то операція підстановки проводиться над спеціальної змінної $ _. Зокрема, попередній приклад можна переписати так:

  $ _ = '/ Usr / bin / perl';
 s | / usr / bin | / usr / local / bin |; 

Крім стандартних, тут можна використовувати такі модифікатори:

модифікатор опис
e Обробляти string як вираз PERLа.
g Глобальна підстановка, т. Е. Заміна всіх входжень зразка.
o Компілювати регулярний вираз тільки один раз.

Ми можемо використовувати замість // будь-який символ, допустимий в q-операціях. Якщо pattern укладений в парні дужки, то string повинен мати власну пару обмежувачів, наприклад s(foo)[bar] або s<foo>/bar/ .

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

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

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

Модифікатор e вказує, що string є виразом. В цьому випадку до string спочатку застосовується функція eval (), а потім проводиться підстановка. приклад:

  $ _ = '123';
 s / \ d + / $ & * 2 / e;  # $ _ = '246'
 s / \ d / $ & * 2 / eg;  # теж саме 

Наведемо ще кілька типових прикладів використання операції підстановки. Видалення коментарів виду / * ... * / з тексту Java- або C-програми:

  $ Program = ~ s {
  / \ * # Початок коментаря
  . *?  # Мінімальна кількість символів
  \ * / # Кінець коментаря
 } [] Gsx; 

Видалення початкових і кінцевих пробілів в рядку $ var:

  for ($ var) {
  s / ^ \ s + //;
  s / \ s + $ //;
 } 

Перестановка двох перших полів в $ _. Зверніть увагу, що в рядку заміни використовуються змінні $ 1 і $ 2, а не метасимволу \ 1 і \ 2:

  s / ([^] *) * ([^] *) / $ 2 $ 1 /; 

Заміна табуляцій на прогалини з вирівнюванням по колонках, кратним восьми:

  1 while s / \ t + / '' x (length ($ &) * 8 - length ($ `)% 8) / e; 

6.4.6.5. транслітерація

  Синтаксис: tr / list1 / list2 / modifiers y / list1 / list2 / modifiers
 

Транслітерація полягає в заміні всіх символів зі списку list1 відповідними символами зі списку list2. Вона повертає кількість замінених або віддалених символів. Списки повинні складатися з окремих символів і / або діапазонів виду az. Преутворена рядок задається лівим операндом операції = ~ або! ~. Вона повинна бути скалярної змінної, елементом масиву або елементом асоціативного масиву, наприклад:

  $ Test = 'ABCDEabcde';
 $ Test = ~ tr / AZ / az /;  # Заміна малих літер на прописні 

Якщо рядок не задана, то операція підстановки проводиться над спеціальної змінної $ _. Зокрема, попередній приклад можна переписати так:

  $ _ = 'ABCDEabcde';
 tr / AZ / az /; 

Ми можемо використовувати замість // будь-який символ, допустимий в q-операціях. Якщо list1 укладений в парні дужки, то list2 повинен мати власну пару обмежувачів, наприклад tr(AZ)[az] або tr<AZ>/az/ .

Зазвичай ця операція називається tr. Синонім y введений для фанатиків редактора sed і використовується тільки ними. Транслітерація підтримує такі модифікатори:

модифікатор опис
c Замінювати символи, що не входять в list1.
d Видаляти символи, для яких немає заміни.
s Видаляти повторювані символи при заміні.
U Перетворювати в / з кодування UTF-8.
C Перетворювати в / з однобайтових кодування.

Модифікатор c викликає транслітерацію всіх символів, що не входять в список list1. Наприклад, операція tr/a-zA-Z/ /c замінить всі символи, які не є латинськими літерами, на прогалини.

За замовчуванням, якщо list2 коротше, ніж list1, він доповнюється останнім своїм символом, а якщо він порожній, то приймається рівним list1 (це зручно для підрахунку кількості символів певного класу в рядку). Модифікатор d змінює ці правила: все символи з list1, яким немає відповідності в list2, видаляються з рядка. Наприклад, операція tr/a-zA-Z//cd видалить з рядка всі символи, які не є латинськими буквами.

Модифікатор s видаляє повтори: якщо кілька символів поспіль замінилися на один і той же символ, то буде залишено тільки один екземпляр цього символу. Наприклад, операція tr/ / /s видаляє в рядку повторювані пробіли.

Модифікатори C і U призначені для перекодування символів з системної кодування в UTF-8 і назад. Перший з них вказує на вихідну кодування, а другий - на кодування результату. Наприклад, tr/\0-\xFF//CU перекодовує рядок з системної кодування в UTF-8, а tr/\0-\xFF//UC виконає зворотну перекодування.

Транслітерація проводиться без інтерполяції списків символів, тому для використання в ній змінних необхідно викликати функцію eval (), наприклад:

  eval "tr / $ oldlist / $ newlist /";