Python中基于字符位置合并和弦与歌词行的实现方法
解决和弦与歌词对齐合并的问题
我明白你的需求了——要把交替的和弦行和歌词行合并,让和弦精准插入到歌词的对应位置,而不是仅仅拿到一个和弦列表。关键在于保留和弦在原行中的位置信息,这样才能对应到歌词的正确位置插入。
核心思路
- 成对读取行:用
zip(f, f)每次读取两行(和弦行+歌词行)的方法是对的,这能保证我们处理的是对应的一组和弦和歌词。 - 提取和弦的位置信息:遍历和弦行,记录每个和弦的起始索引和和弦内容,而不是只拆分出和弦列表。
- 按位置插入和弦:把歌词转成列表(方便插入操作),按和弦的位置从后往前插入(避免插入后影响前面的索引),最后拼接成字符串。
- 处理末尾和弦:如果某个和弦的位置超出了歌词长度,就把它追加到歌词末尾。
完整代码实现
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)
代码说明
parse_chord_positions函数:- 遍历和弦行,跳过空格找到每个和弦的起始位置。
- 读取从起始位置到下一个空格的内容,作为和弦文本。
- 返回每个和弦的(起始索引, 和弦内容)元组列表,比如处理
"C G Am"会得到[(0, 'C'), (2, 'G'), (4, 'Am')]。
insert_chords_into_lyric函数:- 将歌词转为列表(字符串不可变,列表更适合插入操作)。
- 按和弦的起始索引从大到小排序,这样插入后面的和弦不会影响前面的索引位置。
- 检查和弦位置是否在歌词长度范围内,在则插入对应位置,否则追加到末尾。
主程序:
- 用
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
相关产品推荐
相关产品推荐

