【问题标题】:php regex to extract single parameter value from stringphp正则表达式从字符串中提取单个参数值
【发布时间】:2020-04-07 22:54:24
【问题描述】:

我正在处理一个包含参数的字符串,这些参数由 PHP 中的一些特殊字符与 preg_match 分隔

一个例子可能是这样的,它有四个参数。

1stparm?#?1111?@?2ndParm?#?2222?@?3rdParm?#?3333?@?4thparm?#?444?@?

每个参数名后跟?#?,其值紧挨着它,以?@?结尾(注意:值可以是字符串或数字,甚至是特殊字符)

我的正则表达式可能过于复杂,这在某些情况下有效,但如果我搜索字符串中的最后一个参数,则不会..

此示例返回 2222 作为 2ndParm 的正确值(在第 1 组中)

(?:.*)2ndParm\?#\?(.*?)\?@\?(?=.)(.*)

但如果 2ndParm 是字符串中的最后一个,则失败,如下例所示:

1stparm?#?1111?@?2ndParm?#?2222?@?

如果我只返回一组结果,我也很感激。我无法这样做,但由于我总是得到我对第 1 组感兴趣的那个,所以无论如何我都可以很容易地得到它。

【问题讨论】:

    标签: php regex preg-match


    【解决方案1】:

    没有正则表达式:

    $str ='1stparm?#?1111?@?2ndParm?#?2222?@?3rdParm?#?3333?@?4thparm?#?444?@?';
    
    $keyval = explode('?@?', trim($str, '?@'));
    
    $result = [];
    
    foreach($keyval as $item) {
        [$key, $result[$key]] = explode('?#?', $item);
    }
    
    print_r($result);
    

    demo

    【讨论】:

    • 不错的答案 - ++。
    • 同意。又好又短...我开始沉迷于正则表达式,并且太专注于其他地方。
    【解决方案2】:

    你不需要对所有事情都使用正则表达式,你应该与发明这种可怕格式的人认真讨论一下 JSON、YAML、TOML、XML 等存在的事实。

    function bizarre_unserialize($in) {
        $tmp = explode('?@?', $in);
        $tmp = array_filter($tmp); // remove empty
        $tmp = array_map(
            function($a) { return explode('?#?', $a); },
            $tmp
        );
        // rearrange to key-value
        return array_combine(array_column($tmp, 0), array_column($tmp, 1));
    }
    
    $input = '1stparm?#?1111?@?2ndParm?#?2222?@?3rdParm?#?3333?@?4thparm?#?444?@?';
    
    var_dump(
        bizarre_unserialize($input)
    );
    

    输出:

    array(4) {
      ["1stparm"]=>
      string(4) "1111"
      ["2ndParm"]=>
      string(4) "2222"
      ["3rdParm"]=>
      string(4) "3333"
      ["4thparm"]=>
      string(3) "444"
    }
    

    【讨论】:

    • 该格式由 scriptcase RAD 内部使用。它以显示的格式在名为 nmgp_parms 的单个参数中发布用户参数。你也是一个非常有用的解决方案。
    【解决方案3】:

    你可以使用

    (?P<key>.+?)
    \Q?#?\E
    (?P<value>.+?)
    \Q?@?\E
    

    verbose 模式下,请参阅a demo on regex101.com


    \Q...\E 构造禁用 ?# “超级大国”(无需在此处转义它们)。
    PHP 这可能是
    <?php
    $string = "1stparm?#?1111?@?2ndParm?#?2222?@?3rdParm?#?3333?@?4thparm?#?444?@?";
    
    $regex = "~(?P<key>.+?)\Q?#?\E(?P<value>.+?)\Q?@?\E~";
    
    preg_match_all($regex, $string, $matches, PREG_SET_ORDER);
    
    foreach ($matches as $match) {
        echo $match["key"] . " = " . $match["value"] . "\n";
    }
    
    ?>
    

    产量

    1stparm = 1111
    2ndParm = 2222
    3rdParm = 3333
    4thparm = 444
    


    或更短:
    $result = array_map(
        function($x) {return array($x["key"] => $x["value"]);}, $matches);
    print_r($result);
    

    【讨论】:

    • 感谢您的回答。您的方法对我的目的更有用,并且效果很好。我从来没有使用过 \Q \E 这使得思考更容易阅读。谢谢
    猜你喜欢
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 2014-08-25
    • 1970-01-01
    • 1970-01-01
    • 2020-07-13
    • 2021-05-24
    • 1970-01-01
    相关资源
    最近更新 更多