Поліпшите ваші навички створення шаблонів регулярних виразів, Різне, Програмування, статті

Введення


Кожен день UNIX-адміністратори створюють і використовують регулярні вирази (regexps) щоб зіставляти зразки тексту. Більшість мов підтримує деяку реалізацію регулярних виразів. Деякі додатки (типу EMACS) мають можливості пошуку регулярних виразів, регулярні вирази можна використовувати з безліччю інструментів командного рядка. Для будь-якої програми ключ до створення хороших регулярних виразів – це розпізнавання зразка, який містить тільки ту інформацію, яку вам треба перевіряти, так, щоб ніщо інше від вхідних значень не заважало.


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


Використання регулярних виразів (regexps)


Зауважу, що приклади в цій статті є регулярними виразами для Portable Operating System Interface-extended (POSIX-extended). Якщо ви використовуєте їх у командному рядку (з утилітою egrep, Наприклад), слід укладати їх в лапки, як укладають будь-які інші регулярні вирази. Пам’ятайте, що існують відмінності в реалізаціях регулярних виразів, тому, можливо, доведеться адаптувати їх для різних інструментів, додатків або мови програмування, який ви використовуєте.


Повний збіг


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


Це хороший базовий шаблон для пошуку у файлі словника користувача (/ usr / dict / words). Деякі користувачі UNIX переміщують цей файл в / usr / share / dict / words.


Наприклад, скажімо ви забули як пишеться слово fuchsia. У ньому пишеться sh або cs? Все, в чому ви впевнені, це те, що вона починається з fu і закінчується ia.


Спробуємо пошукати за допомогою наступного шаблону:




          $ egrep -i “^fu.*ia$” /usr/dict/words


Прапор -i шукає збіги незалежно від регістру. У цьому прикладі слово fuchsia є єдиним повертається значенням.


Зіставлення рядків, засноване на довжині


Використовуйте метасимвол “фігурні дужки” ({ }) Для завдання конкретного числа збігів в регулярному виразі, як показано в таблиці 1. Коли ви додаєте їх (фігурні дужки) до щойно описаного пошуку повної рядки, ви отримуєте можливість задати довжину рядка.


Таблиця 1.Значення фігурних дужок















Приклад


Опис

{X}  Цей символ зіставляється регулярним виразом X раз.
{X,}  Цей символ зіставляється регулярним виразом X або більше разів.
{X,Y}  Цей символ зіставляється регулярним виразом щонайменше X, але не більше ніж Y раз.

Не все реалізації розширених регулярних виразів підтримують фігурні дужки. В залежності від реалізації фігурні дужки можуть зажадати екранування зворотної похилої рисою (backslash) при використанні.


Можна використовувати це регулярний вираз для отримання набору слів зі словника, упорядкованих за довжиною. Точне число слів, яке ви отримаєте, залежить від числа слів в словниковому файлі системи. Результат буде приблизно таким, як показано в прикладі 1. У цьому прикладі самої розповсюдженний довжиною слова було дев’ять букв, чому в словнику відповідає 32380 слів. Словник не містить слів, в яких 25 або більше букв, і найдовше слово містить не 21 букву, це не disestablishmentarian, як ви могли б подумати, тому що є ще 81 слово такої ж довжини, наприклад superincomprehensible і phoneticohieroglyphic. Приз за найдовше слово в словнику UNIX поділений між п’ятьма словами, включаючи pathologicopsychological.


Приклад 1. Підрахунок слів з числом букв X в словнику




        $ for i in `seq 1 32`
> {
>
echo “There are” `egrep “^.{“$i”}$” /usr/dict/words / wc -l` “$i-letter words in the dictionary.”

> }
There are 52 1-letter words in the dictionary.
There are 155 2-letter words in the dictionary.
There are 1351 3-letter words in the dictionary.
There are 5110 4-letter words in the dictionary.
There are 9987 5-letter words in the dictionary.
There are 17477 6-letter words in the dictionary.
There are 23734 7-letter words in the dictionary.
There are 29926 8-letter words in the dictionary.
There are 32380 9-letter words in the dictionary.
There are 30867 10-letter words in the dictionary.
There are 26011 11-letter words in the dictionary.
There are 20460 12-letter words in the dictionary.
There are 14938 13-letter words in the dictionary.
There are 9762 14-letter words in the dictionary.
There are 5924 15-letter words in the dictionary.
There are 3377 16-letter words in the dictionary.
There are 1813 17-letter words in the dictionary.
There are 842 18-letter words in the dictionary.
There are 428 19-letter words in the dictionary.
There are 198 20-letter words in the dictionary.
There are 82 21-letter words in the dictionary.
There are 41 22-letter words in the dictionary.
There are 17 23-letter words in the dictionary.
There are 5 24-letter words in the dictionary.
There are 0 25-letter words in the dictionary.
There are 0 26-letter words in the dictionary.
There are 0 27-letter words in the dictionary.
There are 0 28-letter words in the dictionary.
There are 0 29-letter words in the dictionary.
There are 0 30-letter words in the dictionary.
There are 0 31-letter words in the dictionary.
There are 0 32-letter words in the dictionary.
$


Порівняння слів


Кутові дужки < і > дуже корисні при проектуванні шаблонів: вони містять в собі слово для порівняння цілком. Вони не зіставлять укладений в них зразок до тих пір, поки слово, яке розглядається в даний момент регулярним виразом, не буде точно відповідати заданому. Слово являє собою набір символів (числа, букви, символи підкреслення), який з обох кінців обмежений знайдене символами, до складу яких входять:



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


Помістимо в кутові дужки слово, щоб шукати зіставлення тільки для нього, наприклад, так:




          <system>


Регулярний вираз в цьому прикладі не вибере слова ecosystem, systemic або system/70, не зіставить воно і рядки, де зразок system знаходиться де завгодно в рядку, – воно виведе лише рядки, що складаються лише з system.


Комбінуйте кутові дужки з круглими, щоб шукати збіги для частин слів.


Для порівняння рядків, що містять слова, що починаються з pre, використовуйте:




          <(pre).*>


Попередній приклад підбирає рядки, що містять слова preface і preposterous, але не spread або Dupre.


Зіставлення подвійних слів


Використовуючи кутові дужки, можна швидко знайти подвійні слова: після слова йде пропуск і потім знову те ж слово. Ви також можете використовувати backreference, який зіставляє частина зразка самому собі і є рекурсивної можливістю більшості сучасних реалізацій регулярних виразів. (Укладіть частина зразка, яку ии хочете зробити еталонної, в круглі дужки і викличте backreference за допомогою бекслеш (“”), після цього запишіть число вкладень слова-зразка: 1 для першої групи круглих дужок, 2 для другої групи круглих дужок і так далі.)


Щоб знайти подвійні слова, шукаємо слово, за яким слід будь-яке число пробілів і знову точно таке ж слово, яке визначили за допомогою зворотного посилання на першу групу круглих дужок:




          (<.*>)( )+1


Цей приклад не знаходить подвійні слова, відокремлені один від одного комою, такі як It “s been a long, long time.


Для пошуку всіх подвійних слів, включаючи ті, що розділені пробілами та іншими знаками пунктуації, використовуйте це:




          (<.*>).?( )+1


Для того щоб порівняння не залежало від регістру символів, використовуйте прапор -i .


Зіставлення часів


Давайте перейдемо до наступної ситуації, з якою ви постійно сталківаететсь: час і дата. Нижче представлена ​​пара порад, як змусити регулярні вирази працювати з коректними зразками часу і дат.


Ви не можете просто шукати двозначні числа, які визначають хвилини і секунди, тому що хвилини і секунди відраховуються від 0 до 59; для їх зіставлення укладіть в дужки відповідні діапазони для десятків і одиниць для кожної з двох колонок:



Без вираження заперечення на початку в останнього прикладу регулярний вираз буде знаходити час без двокрапки. Такий вираз, залежно від ваших вхідних даних, може мати відношення до середньохвильовому радіо (відоме в Сполучених Штатах як AM-радіо), наприклад, 1450 AM.


Зіставлення місяців


Зіставлення 12 місяців вимагає списку, розділеного вертикальної рисою – оператор /, – Але іноді назви місяців скорочуються різними способами.



Зауважте, що для обох прикладів вище May (травень) є винятком. Це єдиний місяць, у якого повна назва співпадає з трьохлітерним скороченням, тому правильно виконане порівняння повинно містити будь-який з двох варіантів написання, для того щоб слова типу Mayflower не викликали хибного істинного значення.


Приклади вище також можуть виявитися непридатними до роботи (шляхом повернення помилкового істинного значення), коли порівнюємо зразком передують символи, відмінні від пропуску або початку рядків. Навряд чи це може статися в художньому тексті, але може статися, наприклад, у вихідному коді програми, де використовується змінна з ім’ям NumOct.


Для вирішення цих проблем, робіть наступне:



Але все ще залишилася потенційна помилка: жоден з цих прикладів не призначений для пошуку в англійській прозі, тому що є шанс, що вони повернуть помилкове збіг, зі словами типу Janelle або Augury. Щоб виправити це, слід укласти кожен місяць в оболонку для слова оболонку для слова (Слово – мається на увазі синтаксична одиниця).


Попередні приклади добре підходять для деяких випадків без будь-яких додаткових кроків для їх модернізації. В інших випадках ці зразки можуть бути значно спрощені: наприклад, якщо ви здійснюєте пошук в лог-файлі, що містить лише числові дані з датами, що включають в себе великі літери, регулярний вираз типу [A-S], Цілком ймовірно, може бути всім тим, що вам знадобиться для знаходження рядків, що містять назви місяців.


Зіставлення дат


Ви можете комбінувати зіставлення, як описано в таблиці 1, Для пошуку дат.


Для того щоб зіставити місяць, день, рік, використовуйте наступне регулярний вираз (апостроф є службовим символом регулярного виразу, тому його слід брати в подвійні лапки):




          “[A-Za-z]{3,10}.? [0-9]{1,2}, ([0-9]{4}/”?[0-9]{2})”


Це регулярний вираз шукає відповідності для дев’яти різних форматів дати:



  1. MONTH [D]D, YY
  2. MONTH [D]D, “YY
  3. MONTH [D]D, YYYY
  4. MON. [D]D, YY
  5. MON. [D]D, “YY
  6. MON. [D]D, YYYY
  7. MON [D]D, YY
  8. MON [D]D, “YY
  9. MON [D]D, YYYY

Невірні істинні значення, що не відповідають дійсності, в даному регулярному виразі, вклюают Order 99, 99. Для того щоб прибрати їх, можна поєднати це регулярний вираз з виразом для місяців, як описано вище, І в підсумку регулярний вираз буде знаходити тільки справжні назви месяцев.Также змініть числові діапазони, щоб уникнути помилкових зіставлень, але це вже не обов’язково, подвійте число можливих форматів до 18, змінюючи положення коми в шаблоні формату дати.


Всі ці зміни були зроблені для регулярного виразу вище. Протестуйте його змінену версію:




          “([^A-Za-z0-9])(Jan(uary/ /.)/Feb(uary/ /.)/Mar(ch/ /.)/
Apr(il/ /.)/May( /.)/Jun(e/ /.)/Jul(y/ /.)/Aug(ust/ /.)/
Sep(tember/ /.)/Oct(ober/ /.)/Nov(ember/ /.)/
Dec(ember/ /.)) [0-3]?[0-9]{1}(,)? ([0-9]{4}/”?[0-9]{2})”


Змініть регулярний вираз так, щоб воно відповідало вашим потребам. Завжди простіше зіставляти зразки, логічно пов’язані зі своїми вхідними даними, ніж рассогласованних з ними. Майбутні покоління можливо побачать незастосовність попереднього регулярного виразу через бага – Y10K, тому що максимально можливий рік, який воно може знайти – 9999.


Зіставлення цілих чисел


Як видно в кількох попередніх прикладах, числовий діапазон, укладений в дужки, – хороший спосіб знаходити числа.


Для зіставлення цілих чисел будь-якої довжини за позначенням числового діапазону поставте “+”; щоб виключити негативні значення, поставте перед позначенням діапазону спеціальний символ “-” (дефіс):




          -?[0-9]+


Попередній приклад успішно знаходить нуль, тому що нуль – одне з можливих значень у заданому проміжку.


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




          -?[0-9]+(.[0-9]+)?


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




          [^-][0-9]+.([0-9]){5,}


Більше зіставлень для реальних ситуацій


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



Висновок


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


Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*