Python正则表达式,不包括多个换行符

2024-05-17 02:37:50 发布

您现在位置:Python中文网/ 问答频道 /正文

所以我在分析文本时遇到了一个问题。我试图解析音乐文件,它们是半格式化的。例如,我试图把合唱团排除在歌词之外。大多数情况下,格式如下所示:

[Chorus: x2]
Some Lyrics
Some More Lyrics

[Verse]
Lyrics
Lyrics

在这种情况下,这两个函数可以正确解析:

subChorus = re.sub(r'\[Chorus.*?\].*?\[', '[', lyrics, flags = re.DOTALL);
subChorus2 = re.sub(r'\[Chorus.*?\].*?(\n{2,})', '', lyrics, flags = re.DOTALL);

然而,有时合唱团是文件的最后一部分:

Lyrics

[Chorus]
Some Lyrics
Other Lyrics

在这种情况下,我想不出正确的表达方式来消除合唱。如果我这么做的话

subChorusEnd = re.sub(r'\[Chorus.*?\].*?$', '', lyrics, flags = re.DOTALL);

它将工作,但是,对于其他文件中的最后合唱部分不在最后,它将删除需要保留的诗句。所有合唱团块与诗句后,至少有两个新行分开。所以我想出了一个解决办法:

subChorusEnd = re.sub(r'\[Chorus.*?\][^(\n{2,})]*?$', '', subChorus4, flags = re.DOTALL);

但它不起作用。有人能给我解释一下正确的正则表达式来让上面的语句工作吗?或者一个更好的方法,只删除一段文本末尾的chorus块,这也会保留最后一个chorus不在末尾的文件。你知道吗


Tags: 文件文本re诗句情况someflags末尾
3条回答

与其使用正则表达式,我更愿意一行一行地浏览歌词,并决定是否使用基本上是一个蹩脚的有限状态机来保留每一行:

lyrics1 = '''Lyrics

[Chorus]
Some Lyrics
Other Lyrics'''

lyrics2 = '''[Chorus: x2]
Some Lyrics
Some More Lyrics

[Verse]
Lyrics
Lyrics'''

def clean(lyrics):
    result = []
    omitting = False
    for line in lyrics.split('\n'):
        if '[Chorus' in line:
            omitting = True
        if '[' in line and '[Chorus' not in line:
            omitting = False
        if not omitting:
            result.append(line)
    return '\n'.join(result)

print(clean(lyrics1))
print('      ')
print(clean(lyrics2))

结果:

Lyrics

      
[Verse]
Lyrics
Lyrics

所以基本上,如果我们看到一个“Chorus”行,我们就打开一个标志,停止输出行;然后,如果我们看到任何括号内的东西不是“Chorus”,我们就把这个标志向后翻转,继续输出行。你知道吗

我不知道您正在解析的实际文件是什么样子的,但是像这样的策略可能比在这个问题上抛出大量正则表达式更有成效。你知道吗

你可以尝试下面的正则表达式来匹配所有的合唱块。你知道吗

\[Chorus.*?\].*?(\n{2,}|$)

DEMO

或者

(?!.*\n\n)\[Chorus.*?\].*?$

它只匹配末尾的chorus块。别忘了在两个正则表达式中启用DOTALL修饰符。你知道吗

DEMO

\[Chorus:[^\]]+\][\s\S]*?(?=\n{2}|$)

试试这冷杉所有的种类合唱。替换通过empty string。参见演示。你知道吗

https://regex101.com/r/vN3sH3/77

相关问题 更多 >