Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中基于字符位置的行合并_Python - Fatal编程技术网

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)

你试过什么?请出示你的密码。(阅读)你失败的尝试似乎与你无关,但它们可以帮助潜在的回答者了解你的具体遭遇。“为什么这不起作用?”类型的问题往往比“我该怎么做?”类型的问题更有效。