2 回答

TA贡献1828条经验 获得超4个赞
试试这个演示:
pattern = r'(?P<Verse>\[[^\]]+])|(?P<Backing>\([^\)]+\))|(?P<Lyrics>[^\[\(]+)'
您可以使用re.finditer来隔离组。
breakdown = {k: [] for k in ('Verse', 'Backing', 'Lyrics')}
for p in pattern.finditer(song):
for key, item in p.groupdict().items():
if item: breakdown[key].append(item)
结果:
{
'Verse':
[
'[Intro]',
'[Chorus: Travis Scott]'
],
'Backing':
[
'(Freeze)',
'(Skrrt, Skrrt)'
],
'Lyrics':
[
'\nD.A. got that dope!\n\n',
'\nIce water, turned Atlantic ',
"\nNightcrawlin' in the Phantom ",
'...'
]
}
为了进一步详细说明该模式,它使用命名组来分隔三个不同的组。使用[^\]+]和相似只是意味着找到所有不是的 ](同样 when\)意味着一切都不是 ))。在歌词部分,我们排除了以[和开头的任何内容(。在对regex101演示链接可以解释组件的详细信息,如果您需要。
如果您不关心主歌词中的换行符,请使用(?P<Lyrics>[^\[\(\n]+)(不包括\n)将您的歌词转换为没有换行符:
'Lyrics': [
'D.A. got that dope!',
'Ice water, turned Atlantic ',
"Nightcrawlin' in the Phantom ",
'...'
]

TA贡献1864条经验 获得超2个赞
您可以使用正则表达式组搜索封闭括号和开放括号之间的文本。如果您的正则表达式中有一个组(圆括号内的子模式),则 re.findall 将只返回这些括号的内容。
例如,"\[(.*?)\]"会发现您只是部分标签,不包括方括号(因为它们在组之外)。
正则表达式"\)(.*?)\("只会找到最后一行(“\nNightcrawlin' in the Phantom”)。
同样,我们可以找到第一行"\](.*?)\["。
将两种类型的括号组合成一个字符类,(看起来非常混乱)正则表达式"[\]\)](.*?)[\[\(]"捕获所有歌词。
它会错过之前或之后没有括号的行(即,如果有的话,在 [Intro] 之前的开头,或者如果之后没有和声的话,则在结尾处)。一种可能的解决方法是在字符串末尾添加“]”字符并将“[”字符附加到末尾以强制匹配开始/结束。请注意,我们需要添加 DOTALL 选项以确保通配符“。” 将匹配换行符 "\n"
import re
lyrics = """[Intro]
D.A. got that dope!
[Chorus: Travis Scott]
Ice water, turned Atlantic (Freeze)
Nightcrawlin' in the Phantom (Skrrt, Skrrt)..."""
matches = re.findall(r"[\]\)](.*?)[\[\(]", "]" + lyrics + "[", re.DOTALL)
main_vocals = '\n'.join(matches)
添加回答
举报