Регулярное выражение (нужна помощь)

dimases

Новичок
Регулярное выражение (нужна помощь)

Задача такая:
Есть так называемый типоразмер шины.
Обычно он задается в виде, например, 175/70R13 - самый популярный и простой вид. Но есть еще другое варианты задания, например, полнопрофильная 175R13, или в дюймах 31x9,6R13, или грузовая 185R14C8, или спортивная 205/60ZR15. Да и вообще есть много других комбинаций. Мне нужно выделить все параметры из любого типоразмера. То есть, логически шаблон такой:

(weight)(/|x)(profile)(R|ZR)(diameter)(C)(cargovalue)

Причем, (/|x)(profile) и (C)(cargovalue) могут быть, а могут не быть.

Я написал такой шаблон:
~(.+)([/]|[x]|^\d?)(.*)([Z]?)([R])(.+)([C])(.*)~i

Но, к сожалению, он работает не на всех вариантах. Очень прошу помощи! Что в нем не верно.

Прошу в мануал не отправлять, так как теорию знаю, а с практикой в данной задаче - проблема. Поэтому и иду за подсказкой!
 

Кром

Новичок
>Но, к сожалению, он работает не на всех вариантах.

А на каких из перечисленных он работает?
 

dimases

Новичок
Бестолку.

'~(.+)([/]|[x]|^\d?)(.*)([R|ZR])(.+)([C])(.*)~i'

Сейчас я сделал так:
'~(.+)([/]|[x]|^\d?)(.*)([Z]?)([R])(.+)([C])?(.*)~i'

165/60ZR13 (не верно):
Array ( [0] => 165/60ZR13 [1] => 165 [2] => / [3] => 60Z [4] => [5] => R [6] => 13 [7] => [8] => )

165/60R13 (верно):
Array ( [0] => 165/60R13 [1] => 165 [2] => / [3] => 60 [4] => [5] => R [6] => 13 [7] => [8] => )

165x60R13 (верно):
Array ( [0] => 165x60R13 [1] => 165 [2] => x [3] => 60 [4] => [5] => R [6] => 13 [7] => [8] => )

165/60R13C8(верно):
Array ( [0] => 165/60R13C8 [1] => 165 [2] => / [3] => 60 [4] => [5] => R [6] => 13C8 [7] => [8] => )

165R13C8 (не верно):
Array ( )
 

Кром

Новичок
Я не совсем уловил почему ты первый пример посчитал не верным. А в остальном, я вижу, что тебе нужно выбирать цифры и их разделители.
Из этого получатеся два подвыражения:
(\d*,\d*|\d*)
и
(R|ZR|\/|x|C|)
соответствено, делая из них цепь, можно распарсить любой типоразмер.
 

dimases

Новичок
1-й, потому что Array ( [0] => 165/60ZR13 [1] => 165 [2] => / [3] => 60Z [4] => [5] => R [6] => 13 [7] => [8] => )
60Z

По поводу \d я думал, но дело в том, что там может быть дробное значение (31x9,6R13). Как тогда.

А вот по последнему по подробнее. Цепь у меня и так есть, вот это "\/" - в синтаксисе есть?
 

Кром

Новичок
>60Z
А, я просто не заметил. Тогда все понятно.

>По поводу \d я думал, но дело в том, что там может быть дробное значение (31x9,6R13). Как тогда.
См. мой пример.

>А вот по последнему по подробнее. Цепь у меня и так есть,

Подвыражения в твоей цепи, если ты еще не заметил, отличаются от подвыражений предложенных мной.

>вот это "\/" - в синтаксисе есть?
Это \ и /
 

dimases

Новичок
Подвыражения в твоей цепи, если ты еще не заметил, отличаются от подвыражений предложенных мной.
А как их совместить?
Так что ли?
~(\d*,\d*|\d*)(R|ZR|\/|x|C|)(\d*,\d*|\d*)(R|ZR|\/|x|C|)(\d*,\d*|\d*)(R|ZR|\/|x|C|)(\d*,\d*|\d*)~

-~{}~ 17.03.06 16:34:

Кажись работает... Щас детальнее проверю.
 

mahoro

Новичок
Я думаю, вам не следует делать одно сложное регулярное выржаение - с ним потом будет сложно работать.
Гораздо проще сделать так:
Код:
if (preg_match('RE для самого распространенного формата', $string, $matches))
    {
    // разобрать массив $matches
    }
elseif (preg_match(.......))
....
И так далее. Люди, которые будут сопровождать эту программу будут вам благодарны.
 

dimases

Новичок
mahoro

Я так делал, но очень много вариантов =(

Кром

Угу... Тока появилась еще задача, чтобы выставить все на свои места (сейчас):


Array ( [0] => 165/60R13 [1] => 165 [2] => / [3] => 60 [4] => R [5] => 13 [6] => [7] => ) - номально

Array ( [0] => 165R13 [1] => 165 [2] => R [3] => 13 [4] => [5] => [6] => [7] => ) - сдвинуто


А надо чтобы, например, 2-й массив:
Array ( [0] => 165R13 [1] => 165 [2] => [3] => [4] => R [5] => 13 [6] => [7] => ) - номальныей вариант

Возможно ли это задать в шаблоне?
 

Кром

Новичок
А надо чтобы, например, 2-й массив:
Array ( [0] => 165R13 [1] => 165 [2] => [3] => [4] => R [5] => 13 [6] => [7] => ) - номальныей вариант
Возможно ли это задать в шаблоне?
Тогда убери из первого разделителя символ R
Из за этого символ R будет найден в следующем разделители и ты получишь нужное смещение.
 

dimases

Новичок
Кром
Тогда убери из первого разделителя символ R
Из за этого символ R будет найден в следующем разделители и ты получишь нужное смещение.
Ну как это? А если 165R13?

Я написал так:
PHP:
function parseSizeTire($value){
  preg_match('~(\d*\.\d*|\d*)(R|ZR|\/|x|C|)(\d*\.\d*|\d*)(R|ZR|\/|x|C|)(\d*\.\d*|\d*)(R|ZR|\/|x|C|)(\d*\.\d*|\d*)~i',$value,$found);
  if (count($found)>0) {
    if ($found[2]=="/" || $found[2]=="x"){
      $tSize=array(
        "weigth" =>$found[1],
        "r1" =>$found[2],
        "profile" =>$found[3],
        "r2" =>$found[4],
        "diameter" =>$found[5],
        "r3" =>$found[6],
        "cargo_value" =>$found[7],
      );
    } else {
        $tSize=array(
          "weigth" =>$found[1],
          "r1" =>"",
          "profile" =>"",
          "r2" =>$found[2],
          "diameter" =>$found[3],
          "r3" =>$found[4],
          "cargo_value" =>$found[5],
        );
      }
    return $tSize;
  }
  return false;
}
-~{}~ 17.03.06 17:00:

А вроде работает:
PHP:
function parseSizeTire($value){
  preg_match('~(\d*\.\d*|\d*)(\/|x|C|)(\d*\.\d*|\d*)(R|ZR|\/|x|C|)(\d*\.\d*|\d*)(R|ZR|\/|x|C|)(\d*\.\d*|\d*)~i',$value,$found);
  if (count($found)>0) {
      $tSize=array(
        "weigth" =>$found[1],
        "r1" =>$found[2],
        "profile" =>$found[3],
        "r2" =>$found[4],
        "diameter" =>$found[5],
        "r3" =>$found[6],
        "cargo_value" =>$found[7],
      );
    return $tSize;
  }
  return false;
}
 
Сверху