【问题标题】:Grouping of regex with same name具有相同名称的正则表达式分组
【发布时间】:2022-01-03 14:27:07
【问题描述】:

我正在尝试编写一个正则表达式来获取成分名称、数量、单位。字符串可以是任何模式,例如“pohe 2 kg OR 2 Kg pohe OR 2Kg Pohe”。 我试过下面的代码 -

<?PHP
    $units = array("tbsp", "ml", "g", "grams", "kg", "few drops"); // add whatever other units are allowed
  
    
    //mixed pattern
    $pattern = '/(?J)(((?<i>^[a-zA-Z\s]+)(?<q>\d*\s*)(?<u>' . join("|", array_map("preg_quote", $units)) . '))|(?<q>^\d*\s*)(?<u>' . join("|", array_map("preg_quote", $units)) . ')(?<i>[a-zA-Z\s]+))/';

    
    $ingredients = '2kg pohe';
    
    preg_match_all($pattern, $ingredients, $m);
    print_r($m);
    $quantities = $m['q'];
    $units = array_map('trim', $m['u']);
    $ingrd = array_map('trim', $m['i']);
    print_r($quantities);
    print_r($units);
    print_r($ingrd);
?>

上面的代码适用于字符串“2kg pohe”,但不适用于“pohe 2kg”。

如果有人知道我缺少什么,请帮助我。

【问题讨论】:

    标签: php regex regex-group


    【解决方案1】:

    对于pohe 2kg,重复的命名组是空的,因为preg_match_all 的文档指出对于标志PREG_PATTERN_ORDER(这是默认值)

    如果模式包含重复的命名子模式,则只有 最右边的子模式存储在 $matches[NAME] 中。

    在您生成的模式中,2kg pohe 在第二部分(交替之后)中有一个匹配项,但对于pohe 2kg,第一部分只有一个匹配项,所以第二部分没有存储的值。

    您可能会做的是使用PREG_SET_ORDER 标志,它给出:

    $ingredients = '2kg pohe';
    preg_match_all($pattern, $ingredients, $m, PREG_SET_ORDER);
    print_r($m[0]);
    

    输出

    Array
    (
        [0] => 2kg pohe
        [i] =>  pohe
        [1] => 
        [q] => 2
        [2] => 
        [u] => kg
        [3] => 
        [4] => 2
        [5] => kg
        [6] =>  pohe
    )
    

    $ingredients = 'pohe 2kg';
    preg_match_all($pattern, $ingredients, $m, PREG_SET_ORDER);
    print_r($m[0]);
    

    输出

    Array
    (
        [0] => pohe 2kg
        [i] => pohe 
        [1] => pohe 
        [q] => 2
        [2] => 2
        [u] => kg
        [3] => kg
    )
    

    然后您可以获得两个字符串的命名子组,例如$m[0]['i'] 等。

    注意,在示例中有2Kg,您可以使模式不区分大小写以匹配。

    【讨论】:

    • 感谢您的帮助。我正在尝试在 js 中做同样的事情。但它不工作。请在下面找到相同的代码。 ``` let pattern = /(((?^[a-zA-Z ]+)(?[0-9 ]*)(?kg|g)|((?[0-9 ]*)(?kg|g)(?^[a-zA-Z ]+)))/g let str = "pohe 2kg" let results = str.matchAll(图案); for(let result of results) { let {ingre, quantity, unit} = result.groups;警报(${ingre}.${quantity}.${unit}); } ``` 这显示错误为 Duplicate capture group name Not getting which modifier for this in js regex
    • @sonalibhat 我认为 Javascript 不支持重复的组名。在这种情况下,您可以省略组名,并检查组号是否有值,因为您知道哪个数字对应于哪个值类型。
    • 您能否分享我提供的示例代码?这对我真的很有帮助
    • @sonalibhat 你可以这样做jsfiddle.net/otgevnfb 如果最初的答案对你有用,请参阅what should I do when someone answers my question?
    • 非常感谢您的帮助。我已接受您的回答,但由于没有投票权,无法投票赞成您的回答。
    猜你喜欢
    • 2011-01-22
    • 2020-11-26
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    相关资源
    最近更新 更多