Python 2.7:使用正则表达式匹配VTT字幕中的字幕事件

Python 2.7:使用正则表达式匹配VTT字幕中的字幕事件,python,regex,python-2.7,webvtt,Python,Regex,Python 2.7,Webvtt,我正在编写一个python脚本来解析VTT字幕文件。 我使用正则表达式匹配和提取特定元素: “在时间码中” “超时代码” “其他信息”(主要是对齐信息,如对齐:中间或直线:-1) 字幕内容(实际文本) 我正在使用标准库中Python的“re”模块,我正在寻找一个正则表达式,它将匹配下面所有(5)个“字幕事件”: WEBVTT 00:00:00.440 --> 00:00:02.320 align:middle line:-1 Hi. 00:00:03.440 --> 00:0

我正在编写一个python脚本来解析VTT字幕文件。 我使用正则表达式匹配和提取特定元素:

  • “在时间码中”
  • “超时代码”
  • “其他信息”(主要是对齐信息,如对齐:中间或直线:-1)
  • 字幕内容(实际文本)
我正在使用标准库中Python的“re”模块,我正在寻找一个正则表达式,它将匹配下面所有(5)个“字幕事件”:

WEBVTT

00:00:00.440 --> 00:00:02.320 align:middle line:-1
Hi.

00:00:03.440 --> 00:00:07.520 align:middle line:-1
This subtitle has one line.

00:00:09.240 --> 00:00:11.080 align:middle line:-2
This subtitle has
two lines.

00:00:15.240 --> 00:00:23.960 align:middle line:-4
Now...
Let's try
four...
lines...

00:00:24.080 --> 00:00:27.080 align:middle
注意,stackoverflow不允许我在代码块的末尾添加空行。通常最后一个“空”行将存在,因为有换行符(
\r\n
\n
)。之后:
00:00:24.080-->00:00:27.080对齐:中间

下面是我的代码。我的问题是,我无法找到一个正则表达式来匹配所有的“字幕事件”(包括一个以空行作为“字幕内容”的事件)

我在代码中尝试了几个正则表达式的变体。一切都没有成功。对我来说也很奇怪的是,如果我把正则表达式组放在一个变量中并打印它们,就像我对这段代码所做的那样,我只会得到最后一行作为
SUBTITLE CONTENT
。但我一定是做错了什么(对吧?)。非常感谢您的帮助


提前感谢。

您的正则表达式与最后一个副标题不匹配的原因如下:

(^.+\n)+\n?
^.+\n
正在查找包含1个或多个字符的行。但文件中的最后一行为空,因此不匹配

subtitle\u content
只包含最后一行的原因也在这里。您正在将每一行逐个与
(^.+\n)+
匹配,即捕获组始终只捕获一行。对于每个匹配的行,捕获组的上一个值将被丢弃,因此最后只剩下最后一行。如果要捕获所有行,必须在捕获组内一次性匹配所有行,例如:

((?:^.+\n)+)

为了使正则表达式正确工作,我稍微更改了最后两行:

(^[0-9]{2}[:][0-9]{2}[:][0-9]{2}[.,][0-9]{3})
[ ]-->[ ]
([0-9]{2}[:][0-9]{2}[:][0-9]{2}[.,][0-9]{3})
([^\n]*)?\n       # replaced `.*` with `[^\n]*` here because of the S-modifier
(.*?)(?:\n\n|\Z)  # this now captures everything up to 2 consecutive
                  # newlines or the end of the string
这个正则表达式需要修饰符
m
(多行)、
s
(单行)当然还有
x
(详细)


看看它的实际效果。

试试,你的模式的最后两行可以变成
(.*)\r?\n([\s\s]*?)\s*(?:(?:\r?\n){2}|\Z)
谢谢你@WiktorStribiż。我想您不需要…
\r?
。。。在那里。在任何情况下,它对我来说都是有效的,没有
\r?
,在Windows机器上有一个测试文件,\r\n用于换行符(Windows样式)。我更喜欢@Aran Fey提供的解决方案,因为(对我来说)它更容易阅读。但是这同样很好,所以感谢堆:)我只是试图提供一个不改变修饰符的提示,
[^\n]
将在文本数据中有
\r
后停止工作。如果您只有
\n
结尾,那么我的建议如下。另外,要理解正则表达式中最后一个子模式的问题,请阅读。谢谢@aranfey,这非常有效。很好的解释。这个正则表达式在多内容行的情况下对我不起作用:例如,
blah-blah-blah(newline),就像我说的blah-blah
所以我更喜欢上面顶部评论中的Wiktor Stribiżew解决方案
(^[0-9]{2}[:][0-9]{2}[:][0-9]{2}[.,][0-9]{3})
[ ]-->[ ]
([0-9]{2}[:][0-9]{2}[:][0-9]{2}[.,][0-9]{3})
([^\n]*)?\n       # replaced `.*` with `[^\n]*` here because of the S-modifier
(.*?)(?:\n\n|\Z)  # this now captures everything up to 2 consecutive
                  # newlines or the end of the string