php 用于从字符串中提取单个参数值的正则表达式

php regex to extract single parameter value from string

我正在处理一个包含参数的字符串,由 PHP 和 preg_match

中的一些特殊字符分隔

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

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

每个参数名后面跟着?#?,它的值就在它的旁边,以?@?结尾(注意:值可以是字符串或数字,甚至可以是特殊字符)

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

此示例 returns 2222 作为 2ndParm

的正确值(在组 1 中)
(?:.*)2ndParm\?#\?(.*?)\?@\?(?=.)(.*)

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

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

我也很感激能帮助我返回一组结果..我没能这样做,但因为我总是得到我对第 1 组感兴趣的那个,所以我可以很容易地得到它.

您可以使用

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

verbose模式下,见a demo on regex101.com


\Q...\E 构造禁用了 ?# "super-powers"(这里不需要转义它们)。
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);

没有正则表达式:

$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

您不需要对所有内容都使用正则表达式,您应该与发明这种可怕格式的人认真讨论 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"
}