2013-02-05 5 views
0

Это простая проблема, но я трачу слишком много времени, пытаясь понять это самостоятельно.php recursive regex

У меня были данные, хранящиеся в строках с рисунком r{N}-{N}s{N}, где {N} - одно- или двухзначное число. Этот шаблон может повторяться до 5 раз. Мне нужно извлечь числа из шаблона, желательно сгруппированные каким-то образом.

Например, если строка была "r4-10s5", я хочу, чтобы извлечь {4,10,5}

Если строка была "r4-10s5r6-7s8" я хочу, чтобы извлечь {4,10,5} {6,7,8}

Как я мог получить это сделать в PHP?

Я пробовал использовать рекурсивные регулярные выражения, но я не могу заставить их правильно соответствовать.

+0

Я тебя не голосовал. Но это произошло из-за того, что вы не представили никаких доказательств того, что на самом деле пытаетесь самостоятельно решить свои собственные решения, вы просто просите других сделать вашу [домашнюю] работу для вас. – sweaver2112

ответ

1
$str = "r4-10s5r6-7s8"; 

preg_match_all("#r(\d{1,2})-(\d{1,2})s(\d{1,2})#", $str, $matches); 

// group the matches together 
$sets = array(); 
for ($i = 0, $count = count($matches[0]); $i < $count; $i++) 
    $sets[] = array($matches[1][$i], $matches[2][$i], $matches[3][$i]); 

print_r($sets); 

Выходы:

array (size=2) 
    0 => 
    array (size=3) 
     0 => string '4' (length=1) 
     1 => string '10' (length=2) 
     2 => string '5' (length=1) 
    1 => 
    array (size=3) 
     0 => string '6' (length=1) 
     1 => string '7' (length=1) 
     2 => string '8' (length=1) 

Другой вариант, который не имеет цикл будет:

preg_match_all("#r(\d{1,2})-(\d{1,2})s(\d{1,2})#", $str, $matches, PREG_SET_ORDER); 

print_r($matches); 

Выходы:

array (size=2) 
    0 => 
    array (size=4) 
     0 => string 'r4-10s5' (length=7) 
     1 => string '4' (length=1) 
     2 => string '10' (length=2) 
     3 => string '5' (length=1) 
    1 => 
    array (size=4) 
     0 => string 'r6-7s8' (length=6) 
     1 => string '6' (length=1) 
     2 => string '7' (length=1) 
     3 => string '8' (length=1) 
+0

+1 Бинго. Спасибо. –

+0

Есть ли прямой способ достичь этой группировки без цикла через массив? –

+1

Да, добавьте 'PREG_SET_ORDER' к вызову preg_match_all. Я отредактировал свой ответ. – Supericy

1

Статическая картина: г - сек и пустые пятна могут быть только номера

/r(\d{1,2})-(\d{1,2})s(\d{1,2})/ => тест здесь: http://regex101.com/r/sH4sY0

\d{1,2} матчей 1 или 2 цифры в строке

-1

Это как бы я это сделать:

function extractNumbers($string, $multiples = 3, $strict = false) { 
    $string = preg_replace('/\D+/', ' ', trim($string)); 
    $array = explode(' ', trim($string)); 
    $count = count($array); 
    $remove = ($count % $multiples); 
    if ($remove > 0) { 
     // Strict, do not allow dangling numbers 
     if ($strict) { 
      return null; 
     } 
     $array = array_slice($array, 0, ($count - $remove)); 
    } 
    $array = array_map('intval', $array); 
    return array_chunk($array, $multiples); 
} 
$str = 'r4-10s5r6-7s8'; 
var_dump(extractNumbers($str)); 

Это может быть не очень элегантно, но я t относительно легко понять и поддерживать.