如何调整ChordPro格式和弦与歌词的打印对齐间距?
解决ChordPro歌词和弦与歌词对齐问题
核心问题是未补偿和弦本身的字符长度:当你从原歌词行中移除[Chord]标记(比如[C]占3个字符),但和弦文本(比如C占1个字符)需要对应到歌词的正确位置,此时需要调整歌词行的空格,避免因移除标记导致的额外空格,同时让和弦行的字符位置与歌词行精准匹配。
解决方案代码
以下是修正后的Node.js解析函数,核心逻辑是追踪和弦位置并计算偏移量,确保和弦与歌词的字符位置一一对应:
function parseChordProLine(line) { const chordRegex = /\[([^\]]+)\]/g; let match; const chordData = []; let cleanLyric = line; // 收集所有和弦及其在原行的相对位置 while ((match = chordRegex.exec(line)) !== null) { const chord = match[1]; // 计算该和弦在移除之前所有和弦标记后的歌词中的位置 const position = match.index - (line.length - cleanLyric.length); chordData.push({ chord, position }); // 移除当前和弦标记,更新干净歌词 cleanLyric = cleanLyric.replace(match[0], ''); } // 初始化和弦行,用空格填充至干净歌词的长度 let chordLine = ' '.repeat(cleanLyric.length); let offset = 0; // 逐个插入和弦,调整位置偏移(因为和弦会占用字符位,后续和弦位置需要偏移) chordData.forEach(({ chord, position }) => { const insertPos = position + offset; // 替换对应位置的空格为和弦 chordLine = `${chordLine.slice(0, insertPos)}${chord}${chordLine.slice(insertPos + chord.length)}`; // 更新偏移量:和弦长度(因为插入和弦后,后续和弦的位置需要向右偏移和弦的长度) offset += chord.length; }); // 对齐两行长度,取最长值补空格 const maxLen = Math.max(chordLine.length, cleanLyric.length); return { chordLine: chordLine.padEnd(maxLen), lyricLine: cleanLyric.padEnd(maxLen) }; } // 测试示例 const sampleLine = "[C]I'm [G]holding on [Am]forever [F]reaching for a [C]hand that's [G]just not [Am]there"; const { chordLine, lyricLine } = parseChordProLine(sampleLine); console.log(chordLine); console.log(lyricLine);
逻辑说明
- 提取和弦与位置:遍历行内容,匹配所有
[Chord]标记,记录和弦文本及其在移除之前所有标记后的歌词中的相对位置。 - 构建和弦行:用空格初始化和弦行,长度与移除标记后的歌词一致,然后逐个插入和弦,同时记录偏移量——因为插入和弦会增加和弦行的长度,后续和弦的位置需要向右偏移已插入和弦的总长度,确保对齐歌词的正确位置。
- 对齐行长度:最终将两行补至相同长度,避免因和弦长度差异导致的换行错位。
效果对比
- 错误输出(未补偿长度):
C G Am F C G Am I'm holding on forever reaching for a hand that's just not there - 修正后输出:
C G Am F C G Am I'm holding on forever reaching for a hand that's just not there
内容的提问来源于stack exchange,提问作者Khalil Bruce
相关产品推荐
相关产品推荐

