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

时间:2014-03-26 18:09:13

标签: php regex preg-match-all

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

3 1/2杯去皮和切丁土豆

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个不同的变量,数组也可以。

3 个答案:

答案 0 :(得分:0)

怎么样:

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

答案 1 :(得分:0)

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

$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'

编辑: 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?这基本上是一个&#34; OR&#34;声明。它正在寻找cuptablespoon。它可以跟scups之后有tablespoons,但?表示它不必在那里。 (s可以在那里,但并非必须如此。)在这个&#34; OR&#34;声明,您可能希望添加其他内容,例如teaspoon|pint|quart|gallon|ounce|oz|box等。由|分隔的每个项目只是它可以匹配的另一项内容。这里的括号将捕获匹配的任何内容并存储它,以便我们以后可以使用它。
  4. \s+与2号相同。
  5. ([-A-Z ]+)字符类[A-Z]查找任何字母。实际上任何大写字母,但你会注意到在表达式之后,我使用不区分大小写的i标志。这使得它将匹配大写或小写字母。此外,我还添加了一些其他字符:-和空格。如果遇到任何其他使匹配失败的字符,您只需将这些字符添加到类中即可。 (例如,你可能在1 Box Sara Lee's Cake Mix中有一个撇号。只需在空格之后将撇号添加到该类中。)+符号表示在该类中至少找到其中一个字符并且括号捕获它找到的任何内容并保存它以便我们以后可以使用它。
  6. 希望这有帮助!

答案 2 :(得分:0)

你可以试试这个:

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 +(。*)$