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

Python中基于字符位置合并和弦与歌词行的实现方法

解决和弦与歌词对齐合并的问题

我明白你的需求了——要把交替的和弦行和歌词行合并,让和弦精准插入到歌词的对应位置,而不是仅仅拿到一个和弦列表。关键在于保留和弦在原行中的位置信息,这样才能对应到歌词的正确位置插入。

核心思路

  1. 成对读取行:用zip(f, f)每次读取两行(和弦行+歌词行)的方法是对的,这能保证我们处理的是对应的一组和弦和歌词。
  2. 提取和弦的位置信息:遍历和弦行,记录每个和弦的起始索引和和弦内容,而不是只拆分出和弦列表。
  3. 按位置插入和弦:把歌词转成列表(方便插入操作),按和弦的位置从后往前插入(避免插入后影响前面的索引),最后拼接成字符串。
  4. 处理末尾和弦:如果某个和弦的位置超出了歌词长度,就把它追加到歌词末尾。

完整代码实现

def parse_chord_positions(chord_line):
    """解析和弦行,返回每个和弦的(起始索引, 和弦内容)列表"""
    chord_positions = []
    index = 0
    line_length = len(chord_line)
    
    while index < line_length:
        # 跳过所有空格,找到和弦的起始位置
        while index < line_length and chord_line[index].isspace():
            index += 1
        if index >= line_length:
            break
        
        # 读取完整的和弦内容(直到下一个空格)
        start_pos = index
        while index < line_length and not chord_line[index].isspace():
            index += 1
        chord = chord_line[start_pos:index].strip()
        chord_positions.append((start_pos, chord))
    
    return chord_positions

def insert_chords_into_lyric(lyric_line, chord_positions):
    """将和弦插入到歌词的对应位置"""
    # 把歌词转成列表,方便插入操作
    lyric_list = list(lyric_line)
    # 按起始索引从大到小排序,避免插入后打乱前面的位置
    sorted_chords = sorted(chord_positions, key=lambda x: x[0], reverse=True)
    
    for pos, chord in sorted_chords:
        if pos <= len(lyric_list):
            # 插入到对应位置
            lyric_list.insert(pos, f'({chord})')
        else:
            # 位置超出歌词长度,追加到末尾
            lyric_list.append(f'({chord})')
    
    return ''.join(lyric_list)

# 主程序:读取文件并处理
if __name__ == "__main__":
    processed_sections = []
    with open('lyrics.txt', 'r', encoding='utf-8') as f:
        # 每次读取两行:和弦行、歌词行
        for chord_line, lyric_line in zip(f, f):
            # 去掉换行符,避免干扰位置计算
            chord_line = chord_line.rstrip('\n')
            lyric_line = lyric_line.rstrip('\n')
            
            # 解析和弦位置
            chord_pos = parse_chord_positions(chord_line)
            # 插入和弦到歌词
            processed_lyric = insert_chords_into_lyric(lyric_line, chord_pos)
            processed_sections.append(processed_lyric)
    
    # 拼接所有段落,得到最终结果
    final_output = ' '.join(processed_sections)
    print(final_output)

代码说明

  1. parse_chord_positions函数:

    • 遍历和弦行,跳过空格找到每个和弦的起始位置。
    • 读取从起始位置到下一个空格的内容,作为和弦文本。
    • 返回每个和弦的(起始索引, 和弦内容)元组列表,比如处理"C G Am"会得到[(0, 'C'), (2, 'G'), (4, 'Am')]。
  2. insert_chords_into_lyric函数:

    • 将歌词转为列表(字符串不可变,列表更适合插入操作)。
    • 按和弦的起始索引从大到小排序,这样插入后面的和弦不会影响前面的索引位置。
    • 检查和弦位置是否在歌词长度范围内,在则插入对应位置,否则追加到末尾。
  3. 主程序:

    • 用zip(f, f)成对读取和弦行和歌词行。
    • 处理每一对行,收集结果后拼接成最终输出。

适配你的示例

假设你的lyrics.txt内容是(严格交替的和弦行和歌词行):

C G Am
See the stone set in your eyes,
F C
see the thorn twist in your side,
G Am F
I wait for you

运行代码后会生成你想要的输出:

(C)See the (G)stone set in your (Am)eyes, see the t(F)horn twist in your s(C)ide, I (G)wait for y(Am)ou(F)

内容的提问来源于stack exchange,提问作者user9219115

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:31:41