Извлечение данных с помощью функции preg_match()

Чтобы извлечь соответствующую часть данных, необходимо вызвать возможность PHP preg_match() с третьим аргументом, обычно называемым «$matches».

Фактические совпадения(если они есть) с регулярным выражением, переданным в виде первого аргумента в preg_match(), в строке, переданной в виде второго аргумента, будут храниться внутри $matches(третьего аргумента). Он представляет собой массив с определенной структурой. Начнем с простого примера, в котором мы используем var_dump() для просмотра структуры массива $matches после того, как было найдено совпадение.

<?php $sequence1 = "CCCGAATTCTTT"; $sequence2 = "CCCTAATTATTT"; $sequences = array($sequence1, $sequence2); $i = 1; // Шаблон $regexp может соответствовать любой из следующих последовательностей// GAATTC// GAATTA// TAATTC// TAATTA$regexp = "/[GT]AATT[CA]/"; foreach($sequences as $sequence){ if(preg_match($regexp, $sequence, $matches)){ echo "<p>n<strong>Match to sequence $i</strong><br>n"; var_dump($matches); echo "</p>n"; } $i++;}?>

Запустив этот preg match PHP пример, мы получим следующее:

Извлечение данных при помощи возможности preg_match()
Как и ожидалось, совпадение с регулярным выражением было найдено в обеих последовательностях.

Какова структура массива $matches, в котором сохраняются найденные совпадения? Так как регулярное выражение не содержало какой-либо части в круглых скобках(используется для создания «захватываемых групп»), $matches включает только один элемент, совпадение, найденное для всего регулярного выражения. var_dumps начинается с «array(1)». Это означает, что $matches — это массив, содержащий один элемент. Для обеих последовательностей это единственный элемент, который имеет в себя индекс 0(«[0] =>») и будет строкой длиной в 6 символов (“string(6)”). Тем не менее, фактическая строка отличается для двух последовательностей. Это «GAATTC» для первой последовательности и «TAATTA» для второй.

Если регулярное выражение(первый аргумент PHP preg_match()) не включает захватываемых групп, массив $matches, переданный во время вызова возможности preg_match() в виде третьего аргумента, будет содержать только один элемент. Он представляет собой часть строки, переданной в preg_match()+ в виде второго элемента, которая соответствует шаблону, определенному всем регулярным выражением. Таким образом, мы не просто знаем, что в строке было найдено совпадение с регулярным выражением, но и что это за совпадение.

Ещё раз рассмотрим тот же пример, но с небольшими изменениями, чтобы обеспечить более чистый отображение и пропустить var_dump:

<?php$sequence1 = "CCCGAATTCTTT";$sequence2 = "CCCTAATTATTT";$sequences = array($sequence1, $sequence2);$i = 1;// Шаблон $regexp может соответствовать любой из следующих последовательностей// GAATTC// GAATTA// TAATTC// TAATTA$regexp = "/[GT]AATT[CA]/";foreach($sequences as $sequence){    if(preg_match($regexp, $sequence, $matches)){ // Вызываем preg_match() с 3 аргументами вместо 2 echo "<p>n<strong>Match to sequence $i</strong><br>n";        echo "Match within sequence <span style="font-family:courier;">$sequence</span> is <span style="font-family:courier;">".$matches[0]."</span>n";        echo "</p>n";    }    $i++;}?>

Мы получим:

Извлечение данных при помощи возможности preg_match()
Нам необходимо сделать так, чтобы preg match utf 8 нашла внутри строки не только первое совпадение с регулярным выражением. В приведенном выше примере, если целевая последовательность была найдена(возможное соответствие шаблону выделено красным цветом):

Извлечение данных при помощи возможности preg_match()
при вызове возможности preg_match() может быть найдено только первое соответствие GAATTC.

Определение в регулярном выражении захватываемых групп при помощи круглых скобок

Во многих случаях может быть надо найти совпадение только с частью шаблона. Можно использовать шаблон для идентификации части строки, содержащей бит(или биты) информации, которая нас действительно интересует. Рассмотрим гипотетическую строку заголовка последовательности FASTA.

Извлечение данных при помощи возможности preg_match()
Красным выделено GI, число, которое можно без труда извлечь из заголовка. Мы могли бы написать такое регулярное выражение для данных строк, чтобы захватить GI:
Извлечение данных при помощи возможности preg_match()
Что означает «любое число, которое повторяется один или пару раз». Это общий шаблон. Ему будет соответствовать 5, 33, 453672 и т. д. Он захватит наш номер GI в этом заголовке, но это просто «случайность».

Вот код c PHP preg match, который можно использовать:

<?php$header = '>gi|197107235|pdb|3CHW|P Chain P, Complex Of Dictyostelium Discoideum Actin';preg_match("/d+/", $header, $matches);echo "<p>".$matches[0]."</p>";

который дает следующий результат:

197107235

В этом ином гипотетическом заголовке:

Извлечение данных при помощи возможности preg_match()
тот же шаблон захватит « 3 », первое число, которое получит функцию preg_match() при вызове, будет ему соответствовать. И это не число GI, которое нам необходимо, его вообще нет в этом заголовке. Попробуйте применить следующий код:

<?php$header = '>pdb|3CHW|P Chain P, Complex Of Dictyostelium Discoideum Acti';preg_match("/d+/", $header, $matches);echo "<p>".$matches[0]."</p>";?>

Чтобы написать конкретный шаблон для GI, который найдет число в заголовке FASTA, воспользуемся синтаксическим контекстом. С его помощью число GI обычно включается в заголовки FASTA. Составим шаблон для preg match PHP примера, который содержит эту информацию.

Контекст числа GI:

Извлечение данных при помощи возможности preg_match()
Составим регулярное выражение, которое имеет этот контекст:

<?php$gi_regexp = "/gi|d+|/"; // Чтобы задать е соответствие горизонтальной черте | необходимо добавить перед ней обратную косую черту, поскольку это метасимвол?>

Но если мы выполним обычный код:

<?php$header = '>gi|197107235|pdb|3CHW|P Chain P, Complex Of Dictyostelium Discoideum Actin';$gi_regexp = "/gi|d+|/";preg_match($gi_regexp, $header, $matches);echo "<p>".$matches[0]."</p>";?>

Вот, что мы получим:

Извлечение данных при помощи возможности preg_match()
Сейчас мы получили нужное число, но оно включено в контекст, который мы определили в регулярном выражении. Не удивительно, что массив $matches сейчас включает в виде уникального элемента совпадение со всем регулярным выражением.

Чтобы приобрести только число, можно без труда использовать в регулярном выражении захватываемую группу. Для этого необходимо заключить часть выражения, которое соответствует числу, в круглые скобки.

Регулярное выражение для PHP preg match сейчас будет выглядеть следующим образом:

<?php$gi_regexp = "/gi|(d+)|/"; // Чтобы задать дословное соответствие горизонтальной черте | необходимо добавить перед ней обратную косую черту, поскольку это метасимвол // Как видите, сейчас часть шаблона, относящая к числу, заключена в скобки?>

Группировка элементов в скобках без создания захватываемой группы

В определенных случаях можно без проблем группировать символы в скобках без создания группы захвата. В этом случае необходимо добавить «?:» сразу же после первой скобки. Например, если вы хотели бы включить в шаблон дополнительную часть «ABC», но ее не необходимо сохранять в массив $matches:

Извлечение данных при помощи возможности preg_match()
Второй знак вопроса означает, что предшествующее выражение будет необязательным.

Ещё одна хитрость: это касается захватываемых групп, которые мы определяем в регулярном выражении. Можно без проблем создать их столько, сколько необходимо. Новый элемент будет автоматически добавлен в массив $matches, содержащий совпадение только с захватываемой группой.

При использовании захватываемых групп в регулярном выражении первый элемент массива $matches все равно будет соответствовать всему выражению. Последующие элементы будут соответствовать захватываемым группам в том порядке, в котором они определены в регулярном выражении.

Если мы используем в preg match PHP примере только одну захватываемую группу, $matches[0] будет содержать фрагмент, соответствующий всему выражению, а $matches[1] — фрагмент, соответствующий захватываемой группе.

Если мы используем две захватываемых группы (два набора скобок), массив $matches будет содержать три элемента: $matches[0] — соответствие всему выражению, $matches[1] — соответствие первой захватываемой группе и $matches[2] — соответствие второй захватываемой группе. Тот же принцип действует при любом числе захватываемых групп, которые используются в выражении.

Вот пример кода, позволяющего определить номер GI :

<?php$header = '>gi|197107235|pdb|3CHW|P Chain P, Complex Of Dictyostelium Discoideum Actin';$gi_regexp = "/gi|(d+)|/";preg_match($gi_regexp, $header, $matches);echo "<p><strong>Match to the entire pattern:</strong><br>".$matches[0]."</p>";echo "<p><strong>Just the GI number:</strong><br>".$matches[1]."</p>";echo '<p><strong>The var_dump of the $matches array:</strong><br>';echo var_dump($matches);echo "</p>";?>

Отображение :

Извлечение данных при помощи возможности preg_match()
В PHP preg match массив $matches сейчас включает два элемента, а не один. Второй элемент включает совпадение с первой. В этом примере только с первой захватываемой группой. Как и в предыдущих примерах, первый элемент $matches по-прежнему включает совпадение со всем регулярным выражением.

Рассмотрим следующую последовательность FASTA :

Извлечение данных при помощи возможности preg_match()
Составим регулярное выражение, которое сможет захватить как идентификатор GI , так и идентификатор PDB . Это релевантная часть заголовка, которая предлагает весь контекст двух идентификаторов:
Извлечение данных при помощи возможности preg_match()
Идентификатор GI состоит только из цифр. Но идентификаторы PDB могут состоять из заглавных букв или цифр, и они содержат четыре символа. Ниже приведено соответствующее регулярное выражение:

<?php$gi_plus_pdb_regexp = "/^>gi|(d+)|pdb|([A-Z1-9]{4})|/";// ^>gi          =>   строка, начинающаяся с >gi// |            =>   далее идет вертикальная черта. Перед ней добавляется обратная косая черта, поскольку вертикальная черта - это метасимвол// (d+)         =>   один или пару символов (идентификатор GI, захватываемая группа 1)// |            =>   вертикальная черта// pdb           =>   три буквы pdb// |            =>   вертикальная черта// ([A-Z1-9]{4}) =>   заглавная буква или цифра, точно 4 символа (идентификатор PDB, захватываемая группа 2)// |            =>   вертикальная черта?>

Сейчас, когда у нас есть соответствующее регулярное выражение для PHP preg match , можно написать небольшой скрипт для анализа файла последовательности FASTA и извлечения идентификатора GI и идентификатора PDB .

<?php$gi_plus_pdb_regexp = "/^>gi|(d+)|pdb|([A-Z1-9]{4})|/";$fasta_sequence = file_get_contents("http://www.cellbiol.com/bioinformatics_web_development/wp-content/uploads/gi-28373620.fasta");$fasta_sequence_lines = explode("n", $fasta_sequence);$gi_id = "not found"; // если идентификатор gi не найден во время выполнения цикла foreach, у нас все равно есть для этого случая определенное значение$pdb_id = "not found";$match_to_whole_regexp = "not found";foreach($fasta_sequence_lines as $line){    if(preg_match($gi_plus_pdb_regexp, $line, $matches)){        $match_to_whole_regexp = $matches[0]; // Первый элемент массива $matches включает соответствие всему регулярному выражению        $gi_id = $matches[1]; // Второй элемент массива $matches включает первую захватываемую группу, идентификатор GI        $pdb_id = $matches[2]; // Третий элемент массива $matches включает вторую захватываемую группу, идентификатор PDB break;    }}// Сейчас мы можем предоставить результатecho "<p><strong>GI ID: </strong>$gi_id</p>";echo "<p><strong>PDB ID: </strong>$gi_id</p>";echo "<p><strong>Whole match: </strong>$match_to_whole_regexp</p>";?>

Вот результат этого скрипта:

Извлечение данных при помощи возможности preg_match()
В виде завершающего preg match PHP примера разберем функции скриптов и регулярных выражений для извлечения всех идентификаторов GI и PDB из файла FASTA , содержащего пару последовательностей.

Вы можете скачать файл здесь . Если внимательно посмотрите на заголовки последовательностей, то заметите, что все они содержат идентификатор GI . Но только некоторые содержат идентификатор PDB . Чтобы не пропустить все идентификаторы GI и PDB , нельзя использовать составленное ранее регулярное выражение, которое захватывает оба идентификатора. Данное выражение предполагает, что оба идентификатора присутствуют в последовательности.

Составим новое регулярное выражение, в котором часть идентификатора PDB будет необязательной.

<?php$gi_plus_pdb_regexp = "/^>gi|(d+)|(?:pdb|([A-Z1-9]{4})|)?/";// ^>gi          =>   строка начинается с >gi// |            =>   далее идет вертикальная черта. Перед ней добавляется обратная косая черта, поскольку вертикальная черта - это метасимвол// (d+)         =>   один или пару символов (идентификатор GI, захватываемая группа 1)// |            =>   вертикальная черта// (?:           =>   группа, но не захватываемая. Отсюда мы можем начать необязательную группу символов, относящуюся к pdb. После данной группы добавляется ?, который указывает, что эта группа будет необязательной// pdb           =>   три буквы pdb// |            =>   a pipe// ([A-Z1-9]{4}) =>   заглавные буквы или цифры, точно четыре символа (идентификатор PDB, захватываемая группа 2)// |            =>   вертикальная черта// )             =>   конец "группы, но не захватываемой", относящейся к pdb// ?             =>   указывает, что предшествующая группа будет необязательной (pdb)?>

Сейчас можно написать программный код PHP preg match , который анализирует файл FASTA с несколькими последовательностями. Результаты будут представлены в таблице.

Также обратите внимание, что мы сохраняем все результаты в массиве $ids . Его элементы представляют собой иные массивы, состоящие из двух элементов. Первый из них — идентификатор GI , а второй — идентификатор PDB . Таким образом, структура массива $ids может быть представлена следующим образом:

Извлечение данных при помощи возможности preg_match()
<?php $gi_plus_pdb_regexp = "/^>gi|(d+)|(?:pdb|([A-Z1-9]{4})|)?/"; // В такой формулировке часть PDB будет необязательной $fasta_sequences = file_get_contents("http://www.cellbiol.com/bioinformatics_web_development/wp-content/uploads/actin-human-partial.fasta"); $fasta_sequence_lines = explode("n", $fasta_sequences); $ids = array(); $seqs_num = 0;$gis_num = 0;$pdb_num = 0; foreach($fasta_sequence_lines as $line){    $gi_id = "not found"; // если идентификатор gi не найден во время исполнения цикла foreach, у нас есть для этого случая отдельное значение    $pdb_id = "not found";    if(preg_match($gi_plus_pdb_regexp, $line, $matches)){ // Мы делаем что-нибудь, только если имеем строку, для которой найдено совпадение        $gi_id = $matches[1];        $gis_num++;        if(array_key_exists(2, $matches)){ // если найдено совпадение для идентификатора PDB            $pdb_id = $matches[2];            $pdb_num++;        }        $ids[] = array($gi_id, $pdb_id); // Для каждой последовательности мы добавляем в конечный массив $ids подмассив с двумя элементами, идентификаторами GI и PDB        $seqs_num++;           }} // Сейчас мы можем предоставить результат // На этот раз мы генерируем соответствующую HTML-страницу с полным заголовком и несколькими стилями CSS, определяющими таблицу с результатамиecho "<!DOCTYPE html>n<html lang="en">n<head>n<meta charset="utf-8">n<title>Test page</title>n<style>td{padding:5px;}thead{font-weight:bold;}</style>n</head>n<body>"; echo "<p>$seqs_num sequences found</p>n";echo "<p>$gis_num GI IDs found</p>n";echo "<p>$pdb_num PDB IDs found</p>n"; echo "<table><thead><tr><th>GI ID</th><th>PDB ID</th></tr><tbody>n"; // Начинаем отображать HTML-код для таблицы foreach($ids as $id_couple){ // для каждой пары идентификаторов GI/PDB мы создаем новую строку таблицы echo "<tr><td>".$id_couple[0]."</td><td>".$id_couple[1]."</td></tr>n";    }echo "</tbody>n</table>n</body>n</html>"; // Закрываем разные теги, открытые до этого ?>

Вы можете вставить данный код и запустить скрипт на сервере или запустить демо-версию .

Если понимаете последний preg match PHP пример, долгий путь изучения данного руководства по регулярным выражениям PHP завершен, поздравляю!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *