1.11: Шаблони (регулярні вирази)
- Page ID
- 6313
У попередніх розділах ми використовували просту програму fasta_stats
для виконання базового аналізу файлу FASTA під назвою PZ_CDNAS.fasta
, здебільшого як привід, щоб дізнатися про стандартні потоки та інструменти, такі як grep
та сортувати
. Виявляється, інформація у файлі PZ_CDNAS.fasta
надає нам багато потенційних питань для обдумування.
Послідовності в цьому файлі насправді є підмножиною передбачуваних стенограм, отриманих з de novo транскриптом збірки для метелика Papilio zelicaon. Кожен рядок заголовка послідовності кодує різноманітну інформацію: другий і третій стовпці рядків заголовка показують кількість зчитувань, що сприяють кожній зібраній послідовності, і середнє покриття послідовності (визначається як загальна кількість баз, внесених читанням, розділене на зібрану послідовність довжина). Навіть ідентифікатори послідовності кодують деяку інформацію: всі вони починаються з псевдовипадкового ідентифікатора, але деякі мають суфікс типу _TY
.
Групи послідовностей, які мають один і той самий суфікс _
, раніше були визначені як мають спільні збіги за допомогою Self-blast. Ідентифікатори послідовності без такого суфікса не мали збігів. Ми можемо запитати: скільки послідовностей у такій групі? На це можна легко відповісти спочатку за допомогою grep
для вилучення рядків, які відповідають >
(рядків заголовка), а потім за допомогою іншого grep
для вилучення тих, хто має шаблон _
(ті, що знаходяться в групі) перед відправкою результату в wc
.
Більш складним питанням було б запитати, скільки різних груп представлено у файлі. Якщо інформація про групу зберігалася в окремому стовпці (скажімо, другий стовпець), на це питання можна відповісти тим же процесом, що і вище, після чого слід сортувати -k2,2d -u
для видалення повторюваних ідентифікаторів груп. Але як ми можемо примусити інформацію групи до власної колонки? Ми могли б зробити це, підставляючи екземпляри _
з пробілами. Інструмент sed
(Stream Editor) може допомогти нам. Ось загальний трубопровід, який ми будемо використовувати:
І ось деякі з вихідних даних, де представлені лише послідовності в групах, і кожна група представлена лише один раз (заміна менше -S
wc
таким чином підрахувала б кількість груп):
Інструмент sed
є складною програмою для зміни вхідних даних (або з файлу або стандартного введення) і друку результатів до стандартного виводу: sed ''
<program><file>або... | sed ''
<program>.
Як awk
, Sed
родом з 1970-х років і надає величезну різноманітність потужних функцій і синтаксису, лише крихітна частина з яких ми розглянемо тут. Зокрема, ми зупинимося на операціях s
, або заміна.
Параметр
[1] Загальним шаблоном програми для заміни є -r
, який ми використовували, дозволяє нам знати, що ми хочемо, щоб наш шаблон був вказаний за допомогою синтаксису «POSIX розширеного регулярного виразу».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_TCATCGCGCGCCCGTCT
до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))
.
- Зіставте або візерунок<pattern x>,
Використовуючи ці фрагменти, ми можемо зібрати регулярний вираз, який служить простим (і насправді не корисним на практиці) відкритим читанням кадрів пошуку. Для прокаріотичних послідовностей (де інтрони не є розглядом), ми визначимо їх як стартовий кодон ATG
, а потім один або кілька кодонів, а потім один з трьох канонічних стоп-кодонів TAA,
або TAG
TGA
. Шаблон для початку - ATG
, і ми бачили, як ми можемо закодувати зупинку вище, за допомогою ((TAA) | (TAG) | (TGA))
. Як щодо «одного або декількох кодонів?» Ну, «один або більше» втілюється в операторі +
, і кодон є будь-які три A, T, C, або G. так, «один або більше кодонів» кодується як ([ACTG] {3,3}) +
. Таким чином, формальний вираз для нашого простого відкритого пошуку кадрів читання:
Насправді регулярні вирази не часто використовуються при пошуку областей кодування (хоча іноді вони використовуються для ідентифікації менших мотивів). Частково причина полягає в тому, що регулярні вирази за замовчуванням жадібні: вони відповідають першому шаблону, який вони можуть, і прагнуть збігатися з якомога більшою частиною рядка. (Стільниковий механізм, який обробляє відкриті кадри читання, таким чином не жадібний.) Розглянемо наступну послідовність, яка має три відкриті кадри читання відповідно до нашого простого визначення та регулярного виразу вище.
Зверніть увагу, що рядок TAG
є одночасно типом кодону загалом ([ACTG] {3,3}
) і зупинкою, тому технічно обидва перші два варіанти дійсні відповідно до формального виразу. За правилами жадібності буде підібрано перше, що ми можемо перевірити простим відлунням
і седом
.
Синтаксис регулярних виразів, який використовується 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 '>'
для вилучення тільки рядків заголовка, ми можемо перевірити це візуально:
Якщо ми надішлемо ці результати через wc
, ми побачимо, що цей файл містить 471 рядок заголовка. Як ми можемо переконатися, що кожен з них відповідає цій схемі? Використовуючи формальний вираз з grep
для шаблону та порівнявши кількість з 471. Оскільки ідентифікатори повинні починатися одразу після символу >
у файлі FASTA, це буде частиною нашого шаблону. Для псевдовипадкового розділу, який може починатися або не починатися з PZ
, але принаймні не повинен містити підкреслення або пробіл, ми можемо використовувати шаблон [^_ [:пробіл:]] +
, щоб вказати один або кілька символів без підкреслення, не пробілів. Для необов'язкового ідентифікатора групи шаблоном буде (_ [A-Z] +) {0,1}
(оскільки {0,1}
робить попереднє необов'язковим). Поклавши їх разом з grep -E
і підрахунок сірників повинен виробляти 471.
Всі заголовки відповідали шаблону, який ми очікували. Що робити, якщо вони цього не зробили? Ми могли б перевірити, які з них не зробили, використовуючи grep -v -E
для друку рядків, які не відповідають шаблону.
Тепер, гіпотетично, припустимо, що (впертий і більш старший) колега визначив список важливих ідентифікаторів генів і відправив їх разом у простому текстовому файлі.
На жаль, схоже, наш колега вирішив використовувати трохи змінену схему іменування, додавши -gene
до кінця кожного псевдовипадкового ідентифікатора перед _
, якщо він присутній. Для того, щоб продовжувати мирну співпрацю, нам може знадобитися змінити наш файл послідовності так, щоб він відповідав цій схемі. Ми можемо зробити це за допомогою sed
, але це буде проблемою, перш за все тому, що ми хочемо виконати вставку, а не підміну. Власне, ми будемо виконувати заміну, але ми будемо замінювати збіги з вмістом від себе!
Що стосується зворотних посилань, у регулярному виразі збіги або підматчі, які згруповані та укладені в дужки, мають відповідні рядки, збережені у змінних\ 1
,\ 2
тощо. Вміст першої пари дужок зберігається в\ 1
, друга в\ 2
(може знадобитися деякі експерименти для визначення місця збереження збігів вкладених дужок). Весь збіг виразу буде збережено у\ 0
.
Щоб завершити приклад, ми змінимо шаблон, який використовується в grep
, щоб захопити обидві відповідні частини шаблону, замінивши їх на\ 1-gene\ 2
.
Вміст PZ_CDNAS.fasta
, після його запуску через sed
вище, виглядає наступним чином:
У самому шаблоні також можуть використовуватися зворотні посилання. Наприклад, 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
і регулярні вирази в цілому допоможуть завершити цю главу.
- Регулярні вирази, хоча і потужні, піддаються помилкам. Працюйте поетапно, і регулярно перевіряйте результати.
- Часто простіше використовувати декілька викликів регулярних виразів (наприклад, з декількома командами
sed
), ніж намагатися створити єдиний складний вираз. - Використовуйте регулярні вирази, де це доречно, але знайте, що вони не завжди доречні. Багато проблем, які можуть здатися природним для регулярних виразів, також природно підходять для інших стратегій, які слід враховувати, враховуючи складність, яку регулярні вирази можуть додати до певної команди або фрагмента коду.
Деякі люди, стикаючись з проблемою, думають: «Я знаю, я буду використовувати регулярні вирази». Зараз у них дві проблеми.
~ Джеймі Завінскі
Вправи
- У файлі статистики збірки de novo
contig_stats.txt
ідентифікатори contig називаються якNODE_1
, NODE_2
тощо. Ми вважаємо за краще, щоб їх називалиcontig1
, contig2
тощо. Створітьфайл contig_stats_renamed.txt
з цими змінами, виконаними. - Скільки послідовностей у файлі
PZ_CDNAS.fasta
складаються тільки з одного прочитаного? Вам, швидше за все, доведеться використовувати якawk
, так іsed
тут, і обов'язково ретельно перевіряйте результати вашого трубопроводу зменшою кількістю
. - Особливо огидний колега наполягає на тому, що в файлі
PZ_CDNAS.fasta
послідовності, які не входять до будь-якої групи (тобто ті, які не мають_
суфікса) повинні мати суфікс_nogroup
. Заспокоїти цього колегу, створивши файл з цією специфікацією під назвоюPZ_CDNAS_Fixed.fasta
. - Рядки заголовків у наборі дріжджового білка
orf_trans.fasta
виглядають так, коли розглядаються зменш -S
після grepping для>:
Примітно, рядки заголовків містять інформацію про розташування окремих екзонів; послідовність YAL001C має два екзони на хромосома I з локацій 151006 до 147594 і 151166 до 151097 (цифри йдуть від великих до малих, оскільки місця вказані на передню пасмо, але ген знаходиться на зворотному пасмі комплементу). На відміну від цього, послідовність YAL002W має тільки один екзон на передню пасмо.Скільки послідовностей складається лише з одного ексона? Далі створіть список ідентифікаторів послідовностей у файлі під назвою
multi_exon_ids.txt
, що містить усі ці ідентифікатори послідовності з більш ніж одним екзоном як один стовпець. - Як продовження питання 4, яка послідовність має найбільше екзонів? Яка одноексонна послідовність є найдовшою, з точки зору відстані від першої позиції до останньої позиції, зазначеної в списку екзонів?
- POSIX, скорочення від інтерфейсу портативної операційної системи, визначає базовий набір стандартів для програм та операційних систем, щоб різні операційні системи, подібні до UNIX, можуть взаємодіяти. م
- Слід також зазначити, що роздільники
/
є найбільш часто використовуваними, але замість них можна використовувати більшість символів; наприклад,s| | |g
<pattern><replacement>може полегшити заміну символів/
. م