将格式化的分隔文本行转换为关联数组

发布于 2024-10-08 13:12:53 字数 375 浏览 7 评论 0原文

我有一串采用以下冒号分隔格式的键->值对:

MIME-Version: 1.0
From: "Tim Lincecum"
Reply-To: "Tim Lincecum"
Return-path: "Tim Lincecum"
Content-Type: text/html; charset=iso-8859-1
Subject: Giants Win World Series!

如何获取一个关联数组,例如 arr['From'] = "Tim Lincecum", 等?

我知道有 explode() 函数,但我看到的唯一分隔符(冒号)位于键和值的中间,而不是在每对之间。我该如何处理这个问题?

I have a string of key->value pairs in the following colon-separated format:

MIME-Version: 1.0
From: "Tim Lincecum"
Reply-To: "Tim Lincecum"
Return-path: "Tim Lincecum"
Content-Type: text/html; charset=iso-8859-1
Subject: Giants Win World Series!

How do I get an associative array such that arr['From'] = "Tim Lincecum", etc.?

I know there's the explode() function, but the only delimiter I see (colon) is in the middle of a key and a value rather than between each pair. How can I approach this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

冷清清 2024-10-15 13:12:53

您始终可以使用正则表达式:)

PHP

$str = 'MIME-Version: 1.0' . "\r\n" .
'From: "Tim Lincecum"' . "\r\n" . 
'Reply-To: "Tim Lincecum"' . "\r\n" . 
'Return-path: "Tim Lincecum"' . "\r\n" . 
'Content-Type: text/html; charset=iso-8859-1' . "\r\n" . 
'Subject: Giants Win World Series!';

preg_match_all('/(.*?):\s?(.*?)(\r\n|$)/', $str, $matches);
 
$headers = array_combine(array_map('trim', $matches[1]), $matches[2]);
 
var_dump($headers);

输出

array(6) {
  ["MIME-Version"]=>
  string(3) "1.0"
  ["From"]=>
  string(14) ""Tim Lincecum""
  ["Reply-To"]=>
  string(14) ""Tim Lincecum""
  ["Return-path"]=>
  string(14) ""Tim Lincecum""
  ["Content-Type"]=>
  string(29) "text/html; charset=iso-8859-1"
  ["Subject"]=>
  string(24) "Giants Win World Series!"
}

在 IDEone 上查看

You could always use regex :)

PHP

$str = 'MIME-Version: 1.0' . "\r\n" .
'From: "Tim Lincecum"' . "\r\n" . 
'Reply-To: "Tim Lincecum"' . "\r\n" . 
'Return-path: "Tim Lincecum"' . "\r\n" . 
'Content-Type: text/html; charset=iso-8859-1' . "\r\n" . 
'Subject: Giants Win World Series!';

preg_match_all('/(.*?):\s?(.*?)(\r\n|$)/', $str, $matches);
 
$headers = array_combine(array_map('trim', $matches[1]), $matches[2]);
 
var_dump($headers);

Output

array(6) {
  ["MIME-Version"]=>
  string(3) "1.0"
  ["From"]=>
  string(14) ""Tim Lincecum""
  ["Reply-To"]=>
  string(14) ""Tim Lincecum""
  ["Return-path"]=>
  string(14) ""Tim Lincecum""
  ["Content-Type"]=>
  string(29) "text/html; charset=iso-8859-1"
  ["Subject"]=>
  string(24) "Giants Win World Series!"
}

See it on IDEone.

知你几分 2024-10-15 13:12:53
$temp = explode("\r\n", $string);
$sets = array();
foreach ($temp as $value) {
    $array = explode(': ', $value);
    $array[1] = trim($array[1], '"');
    $sets[$array[0]] = $array[1];
}

$string 是您从数据库获取的值。

$temp = explode("\r\n", $string);
$sets = array();
foreach ($temp as $value) {
    $array = explode(': ', $value);
    $array[1] = trim($array[1], '"');
    $sets[$array[0]] = $array[1];
}

$string is the value you're getting from the database.

∞梦里开花 2024-10-15 13:12:53

因为我在评论中做了很好的猜测 - 我想我需要在这里重复它作为答案:

参数之间有换行符,因此

$parameters_pairs = explode("\r\n", $parameters_string);

您可以将其拆分为名称-值对,并用冒号分隔。

Since I did a good guess in comments - I think i need to repeat it here as an answer:

There is a newlines between parameters, so with

$parameters_pairs = explode("\r\n", $parameters_string);

you can split it into the name-value pairs, separated with colon.

月朦胧 2024-10-15 13:12:53

在解析本机 PHP 函数/库不处理的文本格式时,避免使用正则表达式方法将需要在一个分隔符上爆炸,然后循环这些结果并在另一个分隔符上爆炸。

为了简单和控制,只需使用 preg_match_all(),然后使用 array_column() 从捕获的子字符串的有效负载形成关联结构。

代码:(演示)

preg_match_all(
    '/^([^:]+): (.+)/m',
    $string,
    $m,
    PREG_SET_ORDER
);
var_export(
    array_column($m, 2, 1)
);

m 模式修饰符更改 ^ 的含义 从“字符串的开头”到“行的开头”。

如果您想删除某些值上出现的双引号,请执行以下模式调整:演示

/^([^:]+): ("?)(.+)\2/m

Avoiding a regular expression approach while parsing a text format that is not handled by a native PHP function/library will require exploding on one delimiter, then looping those results and exploding on another delimiter.

For simplicity and control, just use preg_match_all(), then use array_column() to form the associative structure from the payload of captured substrings.

Code: (Demo)

preg_match_all(
    '/^([^:]+): (.+)/m',
    $string,
    $m,
    PREG_SET_ORDER
);
var_export(
    array_column($m, 2, 1)
);

The m pattern modifier changes the meaning of ^ from "start of the string" to "start of a line".

If you'd like to remove the double quote wrapping that appears on some of the values, here is the pattern adjustment: Demo

/^([^:]+): ("?)(.+)\2/m
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文