【问题标题】:How to handle un-formatted text block returned from shell_exec PHP如何处理从 shell_exec PHP 返回的未格式化的文本块
【发布时间】:2018-05-06 00:32:27
【问题描述】:

我正在使用shell_execSoX 进行交互。这一切都很好,但我对如何处理这个特定问题有点茫然。

使用shell_exec 运行sox --i file.mp3 命令会返回以下未格式化的文本块:

Input File     : '/path/to/audiofile/file.mp3'
Channels       : 2
Sample Rate    : 44100
Precision      : 16-bit
Duration       : 00:06:11.05 = 16363349 samples = 27828.8 CDDA sectors
File Size      : 5.94M
Bit Rate       : 128k
Sample Encoding: MPEG audio (layer I, II or III)

在 PHP 中遍历此文本并将其分配给数组的最佳方法是什么?最好给我类似的东西:

[
    "Input File" => "/path/to/audiofile/file.mp3",  
    "Channels" => 2, 
    "Sample Rate" => 44100,
    "Precision" => "16-bit",

    etc etc..
];

我假设这将是某种形式的高度定制的正则表达式,但我有点不知从何开始。

有什么建议吗?

*EDIT 此问题已被标记为重复,因此被否决。提供的“重复”答案根本对我的情况没有帮助,它解决了一个非常具体的要求,就像我的一样。此外,马里奥对我的问题的第一个回答是“是的,一个非常琐碎的正则表达式。”。不仅没有帮助,而且完全居高临下。很明显,我在这里寻求正则表达式的帮助。

*编辑 2

如果其他人正在为这样的事情苦苦挣扎,我发现了一种非常肮脏、不理想的方法,只要你知道你的输入字符串总是包含相同的键集。

$str = "Input File : '/path/to/audiofile/file.mp3' Channels : 2 Sample Rate : 44100 Precision : 16-bit Duration : 00:06:11.05 = 16363349 samples = 27828.8 CDDA sectors File Size : 5.94M Bit Rate : 128k Sample Encoding: MPEG audio (layer I, II or III)";

$array = preg_split("/[\s,]*\\\"([^\\\"]+)\\\"[\s,]*|" . "[\s,]*'([^']+)'[\s,]*|" . "[\s,]+/", $str, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);

会吐出这样的东西:

Array
(
[0] => Input
[1] => File
[2] => :
[3] => /path/to/audiofile/file.mp3
[4] => Channels
[5] => :
[6] => 2
[7] => Sample
[8] => Rate
[9] => :
[10] => 44100
[11] => Precision
[12] => :
[13] => 16-bit
[14] => Duration
[15] => :
[16] => 00:06:11.05
[17] => =
[18] => 16363349
[19] => samples
[20] => =
[21] => 27828.8
[22] => CDDA
[23] => sectors
[24] => File
[25] => Size
[26] => :
[27] => 5.94M
[28] => Bit
[29] => Rate
[30] => :
[31] => 128k
[32] => Sample
[33] => Encoding:
[34] => MPEG
[35] => audio
[36] => (layer
[37] => I
[38] => II
[39] => or
[40] => III)
)

然后你可以遍历每个元素并用它设置一个新数组:

$newArray = [
    'Input File' => $array[3],
    'Channels' => $array[6],
    etc etc ...
];

【问题讨论】:

  • 我最初认为我可以通过使用冒号 : 分解整个字符串来做到这一点,但是当它达到 Duration 时它会搞砸。
  • 实际上在尝试explode 之后,第一行就搞砸了。
  • 是的,我正在尝试拆分所有内容并重建格式,但在我可以遍历的数组中。

标签: php arrays regex


【解决方案1】:

你可以使用

"~^\h*(.*?)\h*:\h*(?|'([^']+)'|(.*))~m"

请参阅regex demo

详情

  • ^ - 行的开头(m 修饰符使 ^ 也匹配每行的开头)
  • \h* - 0+ 个水平空白字符
  • (.*?) - 第 1 组:除换行符之外的任何 0+ 个字符,尽可能少
  • \h*:\h* - 一个 : 包含 0+ 个水平空白字符
  • (?|'([^']+)'|(.*)) - 与 2 个备选方案中的 1 个匹配的分支重置组:
    • '([^']+)' - 一个',然后是第2组捕获除'之外的任何1+个字符,然后是'
    • | - 或
    • (.*) - 第 2 组:除换行符之外的任何 0+ 个字符,尽可能多(到行尾)

请注意,在branch reset group 中,所有捕获组共享相同的 ID。

PHP demo:

$re = '/^\h*(.*?)\h*:\h*(?|\'([^\']+)\'|(.*))/m';
$str = 'Input File     : \'/path/to/audiofile/file.mp3\'
Channels       : 2
Sample Rate    : 44100
Precision      : 16-bit
Duration       : 00:06:11.05 = 16363349 samples = 27828.8 CDDA sectors
File Size      : 5.94M
Bit Rate       : 128k
Sample Encoding: MPEG audio (layer I, II or III)';

if (preg_match_all($re, $str, $matches)) {
    print_r(array_combine($matches[1], $matches[2]));
}

输出:

Array
(
    [Input File] => /path/to/audiofile/file.mp3
    [Channels] => 2
    [Sample Rate] => 44100
    [Precision] => 16-bit
    [Duration] => 00:06:11.05 = 16363349 samples = 27828.8 CDDA sectors
    [File Size] => 5.94M
    [Bit Rate] => 128k
    [Sample Encoding] => MPEG audio (layer I, II or III)
)

【讨论】:

    猜你喜欢
    • 2010-09-27
    • 2011-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多