You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解析类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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 01:15:58