You can break it apart with an expression like this:
$string = '3 1/2 cups peeled and diced potatoes
1/3 cup diced celery
1/3 cup finely chopped onion
2 tablespoons chicken bouillon granules';
preg_match_all('~([0-9 /]+)\s+(cup|tablespoon)s?\s+([-A-Z ]+)~i', $string, $matches);
That will give you this if you print $matches
:
Array
(
[0] => Array
(
[0] => 3 1/2 cups peeled and diced potatoes
[1] => 1/3 cup diced celery
[2] => 1/3 cup finely chopped onion
[3] => 2 tablespoons chicken bouillon granules
)
[1] => Array
(
[0] => 3 1/2
[1] => 1/3
[2] => 1/3
[3] => 2
)
[2] => Array
(
[0] => cup
[1] => cup
[2] => cup
[3] => tablespoon
)
[3] => Array
(
[0] => peeled and diced potatoes
[1] => diced celery
[2] => finely chopped onion
[3] => chicken bouillon granules
)
)
Although this part isn't really necessary, you can restructure the array to put each item in the format you are asking for. (You can write to the db without putting them in this order, but I will demonstrate here how to put them into the order you are looking for.)
$info_array = array();
for ($i = 0; $i < count($matches); $i++) {
for ($j = 1; $j < count($matches[$i]); $j++) {
$info_array[$i][] = $matches[$j][$i];
}
}
If you printed $info_array
, you'd see this:
Array
(
[0] => Array
(
[0] => 3 1/2
[1] => cup
[2] => peeled and diced potatoes
)
[1] => Array
(
[0] => 1/3
[1] => cup
[2] => diced celery
)
[2] => Array
(
[0] => 1/3
[1] => cup
[2] => finely chopped onion
)
[3] => Array
(
[0] => 2
[1] => tablespoon
[2] => chicken bouillon granules
)
)
You can now loop through that array to put the items into the database:
for ($i = 0; $i < count($info_array); $i++) {
foreach ($info_array[$i] AS $ingredient) {
// INSERT INTO DATABASE HERE
print "<BR>update_database(".$ingredient.")";
}
}
So that would do what you are asking, but I'm assuming that you have some columns that you want to assign these to. You can do something like this if you want to put each piece into its own column:
$info_array = array();
for ($i = 0; $i < count($matches); $i++) {
for ($j = 1; $j < count($matches[$i]); $j++) {
if ($j == 1) {$key = 'amount';}
elseif ($j == 2) {$key = 'size';}
elseif ($j == 3) {$key = 'ingredient';}
$info_array[$i][$key] = $matches[$j][$i];
}
}
print "<PRE><FONT COLOR=ORANGE>"; print_r($info_array); print "</FONT></PRE>";
for ($i = 0; $i < count($info_array); $i++) {
foreach ($info_array[$i] AS $ingredient) {
print "<BR>update_database(".$ingredient.")";
}
}
foreach ($info_array AS $ingredient_set) {
$sql = "INSERT INTO table SET Amount = '".$ingredient_set['amount']."', Size = '".$ingredient_set['size']."', Ingredient = '".$ingredient_set['ingredient']."'";
print "<BR>".$sql;
}
That would give you something like this:
INSERT INTO table SET Amount = '3 1/2', Size = 'cup', Ingredient = 'peeled and diced potatoes'
INSERT INTO table SET Amount = '1/3', Size = 'cup', Ingredient = 'diced celery'
INSERT INTO table SET Amount = '1/3', Size = 'cup', Ingredient = 'finely chopped onion'
INSERT INTO table SET Amount = '2', Size = 'tablespoon', Ingredient = 'chicken bouillon granules'
EDIT: Explanation of the REGEX
([0-9 /]+) \s+ (cup|tablespoon)s? \s+ ([-A-Z ]+)
^ ^ ^ ^ ^
1 2 3 4 5
([0-9 /]+)
Looking for a digit here to capture the amount of whatever measurement you will need. The[0-9]
is a character class that means only grab numbers falling between 0 and 9. Also inside the character class, I added a space and a forward slash to accomodate measurements like3 1/2
. The+
sign means that it has to have at least one of those to make the match. Finally, the parenthesis around this part tell PHP to capture the value and store it as part of the$matches
array so we can do something with it later.\s+
Look for a whitespace character. Because of the+
, we need it to contain at least one, but could be more than one space. I changed this from my initial code just in case there was more than one space.(cup|tablespoon)s?
This is basically an "OR" statement. It's looking for eithercup
ortablespoon
. It can also have ans
after it as incups
ortablespoons
, but the?
means that it doesn't have to be there. (Thes
can be there, but doesn't have to be.) In this "OR" statement, you would probably want to add other things liketeaspoon|pint|quart|gallon|ounce|oz|box
, etc. Each item separated by a|
is just another thing that it could match. The parenthesis here will capture whatever it matched and store it so we can use it later.\s+
Same as number 2.([-A-Z ]+)
The character class[A-Z]
looks for any letters. Actually any UPPERCASE letters, but you'll notice that after the expression, I use the case-insensitivei
flag. This makes it so that it will match uppercase or lowercase letters. Also to this class, I have added a few other characters: the-
and a space. If you run into any other characters like that that make the match fail, you can just add those characters into the class. (For instance, you may have an in apostrophe as in1 Box Sara Lee's Cake Mix
. Just add in the apostrophe into that class after the space.) The+
sign means to find at least one of those characters in that class and the parenthesis capture whatever it found and saves it so that we can work with it later.
Hopefully that helps!