Регулярное выражение для совпадающих величин и единиц - PullRequest
1 голос
/ 07 августа 2010

Мне нужно извлечь количество и единицу из строк, подобных этой

1 tbsp
1tbsp 
300ml
300 ml
10grams
10 g

Количества всегда будут числами, тогда пробел может или не может быть единицей. Это могут быть 15 - 20 различных единиц, которые могут прийти из списка, который мы определяем (возможно, массив)

Решение может быть в javascript или PHP, так как мне нужно разделить их перед сохранением в базе данных. т.е. они должны храниться отдельно.

Спасибо

РЕДАКТИРОВАТЬ: Извините, чтобы быть ясно. Каждая новая строка представляет новую строку. То есть строка будет содержать только 10 г ИЛИ 300 мл - поэтому нам просто нужно разделить одну единицу и одно количество за раз.

Ответы [ 3 ]

4 голосов
/ 07 августа 2010

Регулярное выражение:

/(\d+)\s*(\D+)/

Код:

preg_match_all('/(\d+)\s*(\D+)/', $ingredients, $m);

$quantities = $m[1];
$units = array_map('trim', $m[2]);

$quantities и $units:

Array
(
    [0] => 1
    [1] => 1
    [2] => 300
    [3] => 300
    [4] => 10
    [5] => 10
)
Array
(
    [0] => tbsp
    [1] => tbsp
    [2] => ml
    [3] => ml
    [4] => grams
    [5] => g
)

См .: http://ideone.com/MSH8t

Если вы используете это, вам не нужно иметь готовый список юнитов.Но это предполагает, что в ваших единицах не будет числовых символов, а ваши количества - только цифры.

4 голосов
/ 07 августа 2010

Хорошо, вы можете создать массив разрешенных единиц, а затем использовать array_map, чтобы применить preg_quote к каждой единице в массиве (так что если в модуле есть любые символы, которые являются специальными символами в регулярном выражении (они будут экранированы), а затем создайте регулярное выражение:

$units = array("tbsp", "ml", "g", "grams"); // add whatever other units are allowed
$pattern = '/^(\d+)\s*(' . join("|", array_map("preg_quote", $units)) . ')$/';

Таким образом, $pattern станет чем-то вроде /^(\d+)\s*(tbsp|ml|g|grams)$/, и тогда вы сможете использовать его для обнаружения в вашей строке вещей, похожих на единицы:

$matches = array();
// assuming you have an array of measurement strings...
foreach ($measurement_strings as $measurement)
{
  preg_match($pattern, $measurement, $matches);
  list(, $quantity, $unit) = $matches;
  // ...
}

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

(я обновил свой ответ, основываясь на обновлении вопроса о том, что каждая строка представляет собой отдельную строку).

2 голосов
/ 07 августа 2010

Маби достаточно чего-то простого, вот так:

^([0-9]+)\s*([a-zA-Z]+)\s*$
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...