如何解析类INI格式歌曲内容为关联数组并按指定序列拼接歌曲
问题描述
我正在开发一个歌曲数据库应用,数据库的contents列存储类INI格式的歌曲内容:
[chorus] And all will surely agree, There's nothing like PHP. [1] It may not be the best way, But it isn't going away. [2] When you don't appear to hack it, Check for a closing bracket. [bridge] Oh, if you don't like this ode, Then please don't look at my code.
sequence列存储歌曲播放顺序,例如1,c,2,c,b,1,c(数字对应verse编号,b代表bridge,c代表chorus)。我需要读取数据库后,按正确顺序拼接歌曲内容,各部分之间用空行分隔。
我原本想用parse_ini_string()函数处理,因为内容有[]格式的段头,但这个函数要求段头后必须是var=something;格式的行,显然不符合我的场景。我计划先把歌曲内容转成关联数组,再遍历序列拼接对应内容,另外我有一个序列缩写与段头的映射数组:
$sequenceCodes = array( "1" => "verse 1", "2" => "verse 2", "3" => "verse 3", // ... 其他映射 "p" => "prechorus", "c" => "chorus", "b" => "bridge", "e" => "ending", );
请问该如何实现需求?
实现方案
步骤1:解析contents为关联数组
自己写解析逻辑,逐行处理类INI内容,提取段头和对应歌词:
function parseSongContents($contents) { $lines = explode("\n", trim($contents)); $songParts = []; $currentSection = null; foreach ($lines as $line) { $line = trim($line); // 跳过空行 if (empty($line)) continue; // 识别段头([xxx]格式) if (preg_match('/^\[(.*?)\]$/', $line, $matches)) { $currentSection = $matches[1]; $songParts[$currentSection] = []; continue; } // 非段头行,添加到当前段 if ($currentSection !== null) { $songParts[$currentSection][] = $line; } } // 将每个段的数组转成换行分隔的字符串 foreach ($songParts as &$part) { $part = implode("\n", $part); } unset($part); return $songParts; }
步骤2:处理序列并拼接歌词
利用映射数组将序列缩写转为段头,再从解析后的数组中取出对应内容拼接:
// 示例数据 $contents = "[chorus]\nAnd all will surely agree,\nThere's nothing like PHP.\n[1]\nIt may not be the best way,\nBut it isn't going away.\n[2]\nWhen you don't appear to hack it,\nCheck for a closing bracket.\n[bridge]\nOh, if you don't like this ode,\nThen please don't look at my code."; $sequence = "1,c,2,c,b,1,c"; $sequenceCodes = array( "1" => "1", // 注意:映射值要和contents里的段头完全匹配 "2" => "2", "c" => "chorus", "b" => "bridge", ); // 解析内容 $songParts = parseSongContents($contents); // 拆分序列 $sequenceItems = explode(",", $sequence); // 拼接最终歌词 $finalLyrics = []; foreach ($sequenceItems as $item) { // 通过映射找到对应的段头 $section = $sequenceCodes[$item] ?? null; if ($section && isset($songParts[$section])) { $finalLyrics[] = $songParts[$section]; } } // 各部分用空行分隔 $finalLyrics = implode("\n\n", $finalLyrics); // 输出结果 echo $finalLyrics;
关键说明
- 解析函数会跳过空行,确保关联数组里的歌词无多余空白内容
- 映射数组
$sequenceCodes的值必须和contents里的段头完全匹配(比如原内容段是[1],映射值就写"1";段是[chorus],映射值写"chorus") - 拼接时用
\n\n分隔各部分,符合需求的格式
内容的提问来源于stack exchange,提问作者Transistor
相关产品推荐
相关产品推荐

