如何处理从shell_exec PHP返回的未格式化的文本块

时间:2018-05-06 00:32:27

标签: php arrays regex

我使用shell_execSoX进行互动。这一切都很有效,但我对如何处理这一特定问题感到有点失落。

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

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..
];

我假设它会是某种形式的高度自定义的正则表达式,但我有点不知所措。

有什么建议吗?

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

*编辑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 ...
];

1 个答案:

答案 0 :(得分:2)

您可以使用

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

请参阅regex demo

<强>详情

  • ^ - 该行的开头(m修饰符使得^也在每行的开头匹配)
  • \h* - 0+水平空白字符
  • (.*?) - 第1组:除了换行符之外的任何0 +字符,尽可能少
  • \h*:\h* - 一个{0}包含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]));
}