编写一个简单的正则表达式语句


Writing a simple regular expression statement

我正在寻找用PHP编写正则表达式的帮助。我得到的数据如下:

3杯半去皮切丁的土豆

1/3杯芹菜丁

1/3杯洋葱末

2汤匙鸡汤粉

我把这些都放在一个变量中。我现在正在解析它,以便它存储为3个不同的可用数据项。

我以前从来没有写过正则表达式,我在这里找到了这个指南- http://www.noupe.com/php/php-regular-expressions.html,但我仍然在努力把它应用到我的情况。我也不知道会有多少行输入,可能是1也可能是100

这是我目前所知道的。我已经测试了preg_match语句周围的代码,它正在工作。

preg_match_all("",
    $post_meta,
    $out, PREG_PATTERN_ORDER);

我应该在preg_match_all语句中的"之间放置什么来实现所需的解析?首先感谢你能给予的任何帮助!

编辑

示例输入的期望输出将是:

$var1 = 3 1/2
$var2 = cups
$var3 = peeled and diced potatoes

,然后我可以运行函数来存储数据:

update_database($var1);
update_database($var2);
update_database($var3);

为每一行重复。它不必是3个不同的变量,一个数组也可以。

你可以用这样的表达式把它分开:

$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);

如果你输入$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
        )
)

虽然这部分不是必需的,但是您可以重新构造数组以将每个项放入您所要求的格式。(您可以写入数据库而不将它们按此顺序排列,但我将在这里演示如何将它们按您想要的顺序排列。)

$info_array = array();
for ($i = 0; $i < count($matches); $i++) {
    for ($j = 1; $j < count($matches[$i]); $j++) {
        $info_array[$i][] = $matches[$j][$i];
    }
}

如果您打印$info_array,您将看到:

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
        )
)

现在可以循环遍历该数组,将条目放入数据库:

for ($i = 0; $i < count($info_array); $i++) {
    foreach ($info_array[$i] AS $ingredient) {
        // INSERT INTO DATABASE HERE
        print "<BR>update_database(".$ingredient.")";
    }
}

这就是你想要的,但我假设你有一些列你想要分配这些。如果你想把每一部分放到单独的列中,你可以这样做:

$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;
}

它会给你这样的东西:

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: REGEX的解释

([0-9 /]+)    's+    (cup|tablespoon)s?    's+    ([-A-Z ]+)
     ^         ^              ^             ^          ^
     1         2              3             4          5
  1. ([0-9 /]+)在这里寻找一个数字来捕捉您需要的任何测量量。[0-9]是一个字符类,意味着只抓取0到9之间的数字。同样在字符类中,我添加了一个空格和一个正斜杠来适应3 1/2这样的尺寸。+标志意味着它必须至少有其中一个才能匹配。最后,这部分周围的括号告诉PHP捕获值并将其存储为$matches数组的一部分,以便我们以后可以对它进行处理。
  2. 's+查找空白字符。由于+,我们需要它至少包含一个空格,但可以包含多个空格。我改变了我的初始代码,以防有多个空格。
  3. (cup|tablespoon)s?这基本上是一个"或"语句。它在寻找cuptablespoon。它也可以像cupstablespoons一样在它后面有一个s,但?意味着它不必在那里。(s可以在那里,但不一定要在那里。)在这个"OR"语句中,您可能想要添加其他东西,如teaspoon|pint|quart|gallon|ounce|oz|box等。用|分隔的每个项目都是它可以匹配的另一个项目。这里的括号将捕获匹配的内容并存储起来,以便我们以后使用。
  4. 's+同2
  5. ([-A-Z ]+)字符类[A-Z]查找任意字母。实际上是任何大写字母,但您会注意到,在表达式之后,我使用了不区分大小写的i标志。这使得它可以匹配大写或小写字母。在这个类中,我还添加了一些其他字符:-和一个空格。如果你遇到其他类似的字符导致匹配失败,你可以将这些字符添加到类中。(例如,您可以在1 Box Sara Lee's Cake Mix中使用in撇号。只需在类的空格后面加上撇号即可。)+符号表示在该类中找到至少一个这样的字符,括号捕获它找到的任何字符并保存它,以便我们以后可以使用它。

希望这对你有帮助!

如何:

preg_match_all("~^(['d/ ]+?)'s+('w+)'s+(.+)$~",
    $post_meta,
    $out, PREG_PATTERN_ORDER);

你可以试试:

preg_match_all('/(['d's'/]+)'s+('w+)'s+(.*)$/',
    $post_meta,
    $out, PREG_PATTERN_ORDER);

$var1 = $out[1][0];
$var2 = $out[2][0];
$var3 = $out[3][0];

这是你需要传递的模式:

/((' d ' s/) +) ' s + (' w +) ' s + (. *) $