Skip to main content
LibreTexts - Ukrayinska

1.11: Шаблони (регулярні вирази)

  • Page ID
    6313
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)

    У попередніх розділах ми використовували просту програму fasta_stats для виконання базового аналізу файлу FASTA під назвою PZ_CDNAS.fasta, здебільшого як привід, щоб дізнатися про стандартні потоки та інструменти, такі як grep та сортувати. Виявляється, інформація у файлі PZ_CDNAS.fasta надає нам багато потенційних питань для обдумування.

    Послідовності в цьому файлі насправді є підмножиною передбачуваних стенограм, отриманих з de novo транскриптом збірки для метелика Papilio zelicaon. Кожен рядок заголовка послідовності кодує різноманітну інформацію: другий і третій стовпці рядків заголовка показують кількість зчитувань, що сприяють кожній зібраній послідовності, і середнє покриття послідовності (визначається як загальна кількість баз, внесених читанням, розділене на зібрану послідовність довжина). Навіть ідентифікатори послідовності кодують деяку інформацію: всі вони починаються з псевдовипадкового ідентифікатора, але деякі мають суфікс типу _TY.

    i.11_1_UNIX_133_PZ_CDNAS_Менше

    Групи послідовностей, які мають один і той самий суфікс _, раніше були визначені як мають спільні збіги за допомогою Self-blast. Ідентифікатори послідовності без такого суфікса не мали збігів. Ми можемо запитати: скільки послідовностей у такій групі? На це можна легко відповісти спочатку за допомогою grep для вилучення рядків, які відповідають > (рядків заголовка), а потім за допомогою іншого grep для вилучення тих, хто має шаблон _ (ті, що знаходяться в групі) перед відправкою результату в wc.

    Більш складним питанням було б запитати, скільки різних груп представлено у файлі. Якщо інформація про групу зберігалася в окремому стовпці (скажімо, другий стовпець), на це питання можна відповісти тим же процесом, що і вище, після чого слід сортувати -k2,2d -u для видалення повторюваних ідентифікаторів груп. Але як ми можемо примусити інформацію групи до власної колонки? Ми могли б зробити це, підставляючи екземпляри _ з пробілами. Інструмент sed (Stream Editor) може допомогти нам. Ось загальний трубопровід, який ми будемо використовувати:

    i.11_2_UNIX_134_СЕД_ЕХ1

    І ось деякі з вихідних даних, де представлені лише послідовності в групах, і кожна група представлена лише один раз (заміна менше -S wc таким чином підрахувала б кількість груп):

    i.11_3_UNIX_135_Вийд_ЕХ1_вихід

    Інструмент sed є складною програмою для зміни вхідних даних (або з файлу або стандартного введення) і друку результатів до стандартного виводу: sed '' <program><file>або... | sed ''<program>.

    Як awk, Sed родом з 1970-х років і надає величезну різноманітність потужних функцій і синтаксису, лише крихітна частина з яких ми розглянемо тут. Зокрема, ми зупинимося на операціях s, або заміна.

    I.11_4_SED_Синтаксис

    Параметр -r, який ми використовували, дозволяє нам знати, що ми хочемо, щоб наш шаблон був вказаний за допомогою синтаксису «POSIX розширеного регулярного виразу». [1] Загальним шаблоном програми для заміни є s// /g <pattern><replacement>, де g вказує, що для кожного рядка слід замінити кожен екземпляр шаблону. Ми можемо в якості альтернативи використовувати 1 в цьому місці, щоб вказати, що тільки перший екземпляр повинен бути замінений, 2, щоб вказати лише другий, і так далі. Часто <pattern><replacement>використовується s///, оскільки воно має те саме значення, що і///1 <pattern><replacement>. [2]

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

    Справжня сила sed походить не від його здатності замінювати текст, а від його корисності в заміні тексту на основі «шаблонів» або, більш формально, регулярних виразів. Формальний вираз - це синтаксис для опису відповідності шаблонів у рядках. Регулярні вирази описуються окремими символами, що складають шаблон для пошуку, і «мета-операторами», які змінюють частини шаблону для гнучкості. У [ch] at, наприклад, дужки функціонують як метаоператор, що означає «один з цих символів», і цей патерн відповідає як кішці, так і капелюху, але не спілкуватися. Регулярні вирази часто будуються шляхом ланцюжка менших виразів, як у [ch] at на [mh] at, відповідність кота на капелюсі, кішка на килимку, капелюх на капелюсі та капелюх на килимку.

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

    • символи або рядки, що не є метаоператорами
      • Більшість персонажів, які не працюють в мета-моді, просто підібрані. Наприклад, _ відповідає _, A відповідає A, а ATG відповідає початковому кодону. (Насправді ATG - це три окремі візерунки, зазначені поспіль.) Якщо ви сумніваєтесь, зазвичай безпечно уникнути символу (префіксуючи його зворотною косою рискою рисою рисою), щоб переконатися, що він інтерпретується буквально. Наприклад, \[_\]відповідає літеральному рядку [_], замість використання дужок як метаоператорів.
    • .
      • Період відповідає будь-якому окремому символу. Наприклад, CC. відповідає будь-якому P кодону (CCA, CCT, CCG, CCC), а також рядки, такі як CCX і CC%.
    • [] <charset>
      • Відповідає будь-якому окремому символу, вказаному в<charset>. Наприклад, TA [CT] відповідає кодону Y (TAC або TAT).
    • [^] <charset>
      • Розміщення ^ як першого символу в дужках кодування заперечує значення, таким чином, що будь-який окремий символ, який не названий у дужках, буде зіставлений. TA [^CT] відповідає TAT, TAG, TA% тощо, але не TAC або TAT.
    • ^ (за межами [])
      • Розміщення ^ поза дужками кодування відповідає початку вхідного рядка або рядка. Наприклад, використання sed -r 'S/^atg/xxx/g' замінює всі екземпляри початкових кодонів на XXX, але лише якщо вони існують на початку рядка.
    • $
      • Подібно до ^, але $ відповідає закінченню рядка або рядка. Отже, sed -r 'S/ATG$/xxx/g' замінює всі початкові кодони, які існують в кінці відповідних рядків.

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

    • {x, y}
      • Змінює попередній візерунок таким чином, щоб він збігався, якщо він зустрічається між x та y разів поспіль, включно. Наприклад, [GC] {4,8} відповідає будь-якому рядку C та/або G довжиною від чотирьох до восьми символів (якщо можливо, зйомка для восьми символів). Отже, sed -r 's/ [GC] {4,8} /_x_/G 'призведе до наступних замін:

        • ATCCGTCT
          до АТККГТКТ (без заміни) ATCCGCCGGCTC до
          AT_X_TC
          ATCGCGCGCCCGTCT до AT_X_CCGGT_X_T
      • Використання {0,1} дозволяє зробити те, що слід, необов'язковим у шаблоні, а {x,} дозволяє шаблону відповідати x або більше разів без верхньої межі.
    • *
      • Зірочка змінює попередній шаблон таким чином, щоб він збігався, якщо він зустрічається нуль або більше разів; отже, він еквівалентний {0,}.

        Використання * заслуговує на докладний приклад. Розглянемо патерн ATG [ATGC] *TGA, де ATG - шаблон для початкового кодону, [ATGC] * вказує на нуль або більше основ ДНК поспіль, а TGA є одним з канонічних стоп-кодонів. Цей візерунок відповідає ATGTACCTTGA, а також відповідає ATGTGA (де середня частина була зіставлена нуль разів).

    • +
      • Найбільш помітний модифікатор повторення, знак плюса, змінює попередній візерунок таким чином, щоб він збігався один або кілька разів; він еквівалентний {1,}. На відміну від наведеного вище прикладу, ATG [ATGC] +TGA відповідає ATGTACCTGA і ATGCTGA, але не ATGTGA.
    • () <pattern>
      • Дужки можуть бути використані для групування виразу або серії виразів в одну одиницю, щоб ними можна було працювати разом. Оскільки AT - це візерунок А, за яким слідує T, наприклад, AT+ відповідає AT, ATT, ATTT і так далі. Якщо ми хотіли замість того, щоб відповідати AT повторів, ми могли б задати зразок (AT) +, який відповідає AT, ATAT, ATATAT, і так далі. Дужки також «зберігають» рядок, який був зібраний всередині них, для подальшого використання. Це відоме як зворотне посилання, розглянуте нижче.
    • | <pattern x><pattern y>
      • Зіставте або візерунок<pattern x>, або візерунок<pattern y>. Кілька таких шаблонів або операцій можуть бути прив'язані до ланцюжка; наприклад, TAA|TAG|TGA відповідає будь-якому з трьох канонічних стоп-кодонів. Однак цей приклад дещо неоднозначний: чи читає цей шаблон «TA (A або T) A (G або T) GA,» або «TAA або TAG або TGA»? Щоб зробити його конкретним, ми, ймовірно, хочемо вказати його як ((TAA) | (TAG) | (TGA)).

    Використовуючи ці фрагменти, ми можемо зібрати регулярний вираз, який служить простим (і насправді не корисним на практиці) відкритим читанням кадрів пошуку. Для прокаріотичних послідовностей (де інтрони не є розглядом), ми визначимо їх як стартовий кодон ATG, а потім один або кілька кодонів, а потім один з трьох канонічних стоп-кодонів TAA, TAG або TGA. Шаблон для початку - ATG, і ми бачили, як ми можемо закодувати зупинку вище, за допомогою ((TAA) | (TAG) | (TGA)). Як щодо «одного або декількох кодонів?» Ну, «один або більше» втілюється в операторі +, і кодон є будь-які три A, T, C, або G. так, «один або більше кодонів» кодується як ([ACTG] {3,3}) +. Таким чином, формальний вираз для нашого простого відкритого пошуку кадрів читання:

    I.11_5_Regex_orf

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

    альт

    Зверніть увагу, що рядок TAG є одночасно типом кодону загалом ([ACTG] {3,3}) і зупинкою, тому технічно обидва перші два варіанти дійсні відповідно до формального виразу. За правилами жадібності буде підібрано перше, що ми можемо перевірити простим відлунням і седом.

    I.11_7_UNIX_136_ORF_Команд_рядка_екс

    Синтаксис регулярних виразів, який використовується sed, схожий на синтаксис, який використовується в таких мовах, як Perl, Python і R. Насправді, всі приклади, які ми бачили до цих пір, працюватимуть однаково в цих мовах (хоча вони застосовуються їх власні специфічні функції, а не виклик sed). Однією з корисних функцій, що надаються більш сучасними двигунами регулярних виразів, як ці, є те, що оператори, такі як * і +, можуть бути зроблені нежадібними (хоча я віддаю перевагу більш чіткому терміну «неохоче»), слідуючи за ними зі знаком питання. У Python формальний вираз ATG ([ACTG] {3,3}) +? ((TAA) | (TAG) | (TGA)) буде відповідати другому варіанту. (Якщо не слідує*, або +, це робить попередній необов'язковий; таким чином TG (T)? CC еквівалентно TG (T) {0,1} CC.) Більш складні функції дозволяють користувачеві отримати доступ до всіх збігів шаблону, навіть якщо вони перекриваються, так що найбільш задовольняє один може бути витягнутий за деякими вторинними критеріями. На жаль, sed не підтримує нежадібне узгодження та деякі інші розширені функції регулярних виразів.

    Класи символів та регулярні вирази в інших інструментах

    Ми часто хочемо використовувати дужки кодування, щоб відповідати будь-якому з «класу» символів; наприклад, [0123456789] відповідає будь-якій одній цифрі. Більшість синтаксисів регулярних виразів (включаючи те, що використовується sed) дозволяють скорочену версію [0-9] (якщо ми хочемо відповідати лише 0, 9 або -, ми могли б використовувати [09-]). Аналогічно, [a-z] відповідає будь-якій маленькій літері, а [A-Z] будь-якій великій літері. Вони навіть можуть бути об'єднані: [A-za-z0-9] відповідає будь-якій цифрі або букві. У розширеному синтаксисі POSIX, який використовується sed, 0-9 також можна вказати як [:цифра:]. Зверніть увагу на відсутність дужок у першому - щоб насправді відповідати будь-якій одній цифрі, регулярний вираз є [[:digit:]] (що, так, дратує). Щоб відповідати будь-якій нецифрі, ми можемо скасувати набір у дужках як [^ [:digit:]].

    Ці класи символів POSIX особливо корисні, коли ми хочемо відповідати типам символів, які важко вводити або перерахувати. Зокрема, [[:space:]] відповідає одному з будь-яких пробілів (пробіли, табуляції, нові рядки), а [[:punct:]] відповідає будь-якому символу «пунктуації», яких існує досить багато. Клас символів [[:space:]] особливо корисний, коли ви переформатуєте дані, що зберігаються у рядках і стовпцях, але не впевнені, чи роздільники стовпців є пробілами, табуляціями або деякою комбінацією.

    У багатьох синтаксисах регулярних виразів (включаючи ті, які використовуються Perl, Python, R та деяких версій sed) доступні ще коротші скорочення для класів символів. У них\ d еквівалентно [[:цифра:]],\ D еквівалентно [^ [:цифра:]],\ s для [[:пробіл:]],\ S для [^ [:пробіл:]], серед інших.

    Як з'ясовується, регулярні вирази можуть бути використані grep, а також awk. При використанні grep ми можемо вказати, що шаблон слід розглядати як розширений формальний вираз, додавши прапор -E (на відміну від -r, який використовується для sed.) Таким чином grep -E '[[:digit:]] +' витягує рядки, які містять ціле число.

    У awk ми можемо використовувати ~ компаратор замість == компаратор у if-операторі, як у awk '{if ($1 ~ /PZ718 [[:digit:]] +/) {print $3}}', який друкує третій стовпець кожного рядка, де перший стовпець відповідає шаблону PZ718 [[:digit:]] +.

    Назад Посилання

    Відповідно до описаного вище визначення рядків заголовків у файлі PZ_CDNAS.fasta, ідентифікатори повинні характеризуватися як псевдовипадковий ідентифікатор, за яким, необов'язково, вказується символ підкреслення та набір великих літер, що вказують групу. Використовуючи grep '>' для вилучення тільки рядків заголовка, ми можемо перевірити це візуально:

    I.11_8_UNIX_137_PZ_CDNA_Заголовок_фрагмент

    Якщо ми надішлемо ці результати через wc, ми побачимо, що цей файл містить 471 рядок заголовка. Як ми можемо переконатися, що кожен з них відповідає цій схемі? Використовуючи формальний вираз з grep для шаблону та порівнявши кількість з 471. Оскільки ідентифікатори повинні починатися одразу після символу > у файлі FASTA, це буде частиною нашого шаблону. Для псевдовипадкового розділу, який може починатися або не починатися з PZ, але принаймні не повинен містити підкреслення або пробіл, ми можемо використовувати шаблон [^_ [:пробіл:]] +, щоб вказати один або кілька символів без підкреслення, не пробілів. Для необов'язкового ідентифікатора групи шаблоном буде (_ [A-Z] +) {0,1} (оскільки {0,1} робить попереднє необов'язковим). Поклавши їх разом з grep -E і підрахунок сірників повинен виробляти 471.

    i.11_9_UNIX_138_PZ_CDNA_заголовки_рег_перевірити

    Всі заголовки відповідали шаблону, який ми очікували. Що робити, якщо вони цього не зробили? Ми могли б перевірити, які з них не зробили, використовуючи grep -v -E для друку рядків, які не відповідають шаблону.

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

    I.11_9_UNIX_138_2_PZ_CDNA_заголовки_потреби_виправити

    На жаль, схоже, наш колега вирішив використовувати трохи змінену схему іменування, додавши -gene до кінця кожного псевдовипадкового ідентифікатора перед _, якщо він присутній. Для того, щоб продовжувати мирну співпрацю, нам може знадобитися змінити наш файл послідовності так, щоб він відповідав цій схемі. Ми можемо зробити це за допомогою sed, але це буде проблемою, перш за все тому, що ми хочемо виконати вставку, а не підміну. Власне, ми будемо виконувати заміну, але ми будемо замінювати збіги з вмістом від себе!

    Що стосується зворотних посилань, у регулярному виразі збіги або підматчі, які згруповані та укладені в дужки, мають відповідні рядки, збережені у змінних\ 1,\ 2 тощо. Вміст першої пари дужок зберігається в\ 1, друга в\ 2 (може знадобитися деякі експерименти для визначення місця збереження збігів вкладених дужок). Весь збіг виразу буде збережено у\ 0.

    Щоб завершити приклад, ми змінимо шаблон, який використовується в grep, щоб захопити обидві відповідні частини шаблону, замінивши їх на\ 1-gene\ 2.

    I.11_10_SED_заголовка_виправити

    Вміст PZ_CDNAS.fasta, після його запуску через sed вище, виглядає наступним чином:

    I.11_11_UNIX_139_PZ_CDNA_заголовки_виправлення

    У самому шаблоні також можуть використовуватися зворотні посилання. Наприклад, sed -r 's/ ([A-za-z] +)\ 1/\ 1/g' замінить «подвоєні» слова ([a-za-z] +)\ 1 єдиною копією слова\ 1, як в мені дуже подобається sed, в результаті чого мені дуже подобається sed. Але будьте обережні, якщо ви думаєте про використання підміни такого роду в якості перевірки граматики, тому що цей синтаксис не шукає через межі рядків (хоча більш складні програми sed можуть). Цей приклад не змінить наступну пару рядків (де слово that з'являється двічі):

    The quick sed regex modifies the
    the lazy awk output.

    Кілька заключних заміток про sed і регулярні вирази в цілому допоможуть завершити цю главу.

    1. Регулярні вирази, хоча і потужні, піддаються помилкам. Працюйте поетапно, і регулярно перевіряйте результати.
    2. Часто простіше використовувати декілька викликів регулярних виразів (наприклад, з декількома командами sed), ніж намагатися створити єдиний складний вираз.
    3. Використовуйте регулярні вирази, де це доречно, але знайте, що вони не завжди доречні. Багато проблем, які можуть здатися природним для регулярних виразів, також природно підходять для інших стратегій, які слід враховувати, враховуючи складність, яку регулярні вирази можуть додати до певної команди або фрагмента коду.

    Деякі люди, стикаючись з проблемою, думають: «Я знаю, я буду використовувати регулярні вирази». Зараз у них дві проблеми.

    ~ Джеймі Завінскі

    Вправи

    1. У файлі статистики збірки de novo contig_stats.txt ідентифікатори contig називаються як NODE_1, NODE_2 тощо. Ми вважаємо за краще, щоб їх називали contig1, contig2 тощо. Створіть файл contig_stats_renamed.txt з цими змінами, виконаними.
    2. Скільки послідовностей у файлі PZ_CDNAS.fasta складаються тільки з одного прочитаного? Вам, швидше за все, доведеться використовувати як awk, так і sed тут, і обов'язково ретельно перевіряйте результати вашого трубопроводу з меншою кількістю.
    3. Особливо огидний колега наполягає на тому, що в файлі PZ_CDNAS.fasta послідовності, які не входять до будь-якої групи (тобто ті, які не мають _ суфікса) повинні мати суфікс _nogroup. Заспокоїти цього колегу, створивши файл з цією специфікацією під назвою PZ_CDNAS_Fixed.fasta.
    4. Рядки заголовків у наборі дріжджового білка orf_trans.fasta виглядають так, коли розглядаються з менш -S після grepping для >:I.11_12_UNIX_139_2_ORF_TRANS_заголовки Примітно, рядки заголовків містять інформацію про розташування окремих екзонів; послідовність YAL001C має два екзони на хромосома I з локацій 151006 до 147594 і 151166 до 151097 (цифри йдуть від великих до малих, оскільки місця вказані на передню пасмо, але ген знаходиться на зворотному пасмі комплементу). На відміну від цього, послідовність YAL002W має тільки один екзон на передню пасмо.

      Скільки послідовностей складається лише з одного ексона? Далі створіть список ідентифікаторів послідовностей у файлі під назвою multi_exon_ids.txt, що містить усі ці ідентифікатори послідовності з більш ніж одним екзоном як один стовпець.

    5. Як продовження питання 4, яка послідовність має найбільше екзонів? Яка одноексонна послідовність є найдовшою, з точки зору відстані від першої позиції до останньої позиції, зазначеної в списку екзонів?

    1. POSIX, скорочення від інтерфейсу портативної операційної системи, визначає базовий набір стандартів для програм та операційних систем, щоб різні операційні системи, подібні до UNIX, можуть взаємодіяти. م
    2. Слід також зазначити, що роздільники/є найбільш часто використовуваними, але замість них можна використовувати більшість символів; наприклад, s| | |g <pattern><replacement>може полегшити заміну символів/. م
    • Was this article helpful?