Python中基于字符位置的行合并
我有一个文件,里面有交替的线条、和弦和歌词:Python中基于字符位置的行合并,python,Python,我有一个文件,里面有交替的线条、和弦和歌词: 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, s
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)
从中可以看出,可以使用
with open('lyrics.txt') as f:
for line1, line2 in zip(f, f):
... # process lines
但是,如何合并行,以便根据第1行的角色位置(和弦)拆分第2行?简单的
chords = line1.split()
没有职位信息和
for i, c in enumerate(line1):
...
给出单独的字符,而不是和弦。可以用于从第1行提取和弦的位置和内容。边缘必须小心;同一和弦可能在下一行继续,一行可能包含没有匹配歌词的和弦。这两种情况都可以在示例数据中找到
import io
import re
# A chord is one or more consecutive non whitespace characters
CHORD = re.compile(r'\S+')
def inline_chords(lyrics):
for chords, words in zip(lyrics, lyrics):
# Produce a list of (position, chord) tuples
cs = [
# Handles chords that continue to next line.
(0, None),
# Unpack found chords with their positions.
*((m.start(), m[0]) for m in CHORD.finditer(chords)),
# Pair for the last chord. Slices rest of the words string.
(None, None)
]
# Remove newline.
words = words[:-1]
# Zip chords in order to get ranges for slicing lyrics.
for (start, chord), (end, _) in zip(cs, cs[1:]):
if start == end:
continue
# Extract the relevant lyrics.
ws = words[start:end]
if chord:
yield f"({chord})"
yield ws
yield "\n"
边缘可以用不同的方式处理,例如,通过测试第一个和弦是否在循环之前的0处开始,但是我觉得单for循环使代码更清晰
试一试:
test = """\
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
"""
if __name__ == '__main__':
with io.StringIO(test) as f:
print("".join(list(inline_chords(f))))
生成所需的格式:
(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)
你试过什么?请出示你的密码。(阅读)你失败的尝试似乎与你无关,但它们可以帮助潜在的回答者了解你的具体遭遇。“为什么这不起作用?”类型的问题往往比“我该怎么做?”类型的问题更有效。