Сопоставление шаблонов регулярных выражений

Я полный новичок, когда дело доходит до регулярных выражений, и мне нужен способ сопоставить следующий шаблон:

0hv05d_1a8198c8c430c2333fd6e49863f59f60_d41d8cd98f00b204e9800998ecf8427e_3600_3_25

Объяснение:

Есть 6 разделов, разделенных символом подчеркивания. Первый раздел всегда состоит из 6 символов [a-zA-Z0-9]. Вторая и третья секции представляют собой хеши MD5, поэтому каждая из них всегда будет состоять из 32 символов [a-zA-Z0-9]. Последние 3 раздела могут быть только числами.

Для этого я использую PHP preg_match.

Заранее спасибо.


person Vitaliy Isikov    schedule 23.05.2011    source источник
comment
Попробуйте прочитать эту страницу: regular-expressions.info/reference.html от начала до конца.   -  person Richard Garside    schedule 23.05.2011


Ответы (5)


Вы можете попробовать:

<?php
$string = '0hv05d_1a8198c8c430c2333fd6e49863f59f60_d41d8cd98f00b204e9800998ecf8427e_3600_3_25';
if (preg_match('/([a-zA-Z0-9]{6})_([a-fA-F0-9]{32})_([a-fA-F0-9]{32})_([0-9]+)_([0-9]+)_([0-9]+)/',$string,$match)) {
    print_r( $match );
}
?>
person AndersTornkvist    schedule 23.05.2011
comment
Отлично работает, за исключением того, что если я добавляю буквы между числами в последних трех разделах, он все равно становится положительным, если я не возвращаю значения в $match. В любом случае, этого достаточно для того, что мне нужно. Спасибо! - person Vitaliy Isikov; 23.05.2011
comment
@Vitality Isikov Странно. Я не могу это объяснить. Пожалуйста! - person AndersTornkvist; 23.05.2011

Вот самое короткое, что я могу сделать, основываясь на ваших (несколько неполных) спецификациях:

preg_match('/[a-z\d]{6}(?:_[a-f\d]{32}){2}(?:_\d+){3}/i', $string);

Это будет соответствовать ровно шести экземплярам буквы или цифры; за которым следует символ подчеркивания и 32 шестнадцатеричных цифры дважды; с последующим подчеркиванием и любым количеством цифр, 3 раза. /i в конце переводит его в режим без учета регистра.

person David Z    schedule 23.05.2011

$string = "0hv05d_1a8198c8c430c2333fd6e49863f59f60_d41d8cd98f00b204e9800998ecf8427e_3600_3_25";
if (preg_match('/^([a-z0-9]{6})_([a-f0-9]{32})_([a-f0-9]{32})_([0-9]+)_([0-9]+)_([0-9]+)$/i', $string, $matches))
{
    echo "Match!<br />\n";
    echo "First: ".$matches[1]."<br />\n";
    echo "MD5 hashes: ".$matches[2]. " - ".$matches[3]."<br />\n";
    echo "numbers: ".$matches[4]. " - ".$matches[5]. " - ".$matches[6]."<br />\n";
}

примечания:

  • md5 — это просто [a-f0-9], а не [a-z0-9].
  • Я поставил /i для совпадения без учета регистра вместо того, чтобы указывать [a-zA-Z] в каждой части.
person Carlos Campderrós    schedule 23.05.2011
comment
Я редактировал его несколько раз, если все еще не работает, замените \d на [0-9] (сейчас редактирую) - person Carlos Campderrós; 23.05.2011
comment
Я сказал, что весь текст, который вы пытаетесь сопоставить, является образцом, который вы сказали. Если вам нужно сопоставить этот шаблон с большим текстом, удалите ^ в начале шаблона и $ в конце. - person Carlos Campderrós; 23.05.2011

Изменить. Чтобы быть более полным, вы можете сделать это:

if (preg_match('/[a-z0-9]{6}_[a-f0-9]{32}_[a-f0-9]{32}_\d+_\d+_\d+/i', $subject)) {
    # Successful match
} else {
    # Match attempt failed
}

Я также, чтобы сделать его более кратким, заменил [0-9] классом \d, изменил соответствие MD5 просто на [a-f0-9], а также заменил [a-zA-Z0-9] на [a -z0-9] и включает /i для нечувствительности к регистру.

Если бы вы действительно хотели, выражение также можно было бы переписать как:

/[a-z0-9]{6}(?:_[a-f0-9]{32}){2}(?:_\d+){3}/i

person daalbert    schedule 23.05.2011

[a-zA-Z0-9]{6}_[a-f0-9]{32}_[a-f0-9]{32}_[0-9]+_[0-9]+_[0-9]+

ссылка: http://www.php.net/manual/en/reference.pcre.pattern.syntax.php

Кроме того, поскольку php использует PCRE (Pearl Compatible Regular Expressions), вы можете использовать эту изящную шпаргалку: http://www.addedbytes.com/cheat-sheets/regular-expressions-cheat-sheet/

person colinross    schedule 23.05.2011