使用正则表达式从 webvtt 中提取
Extracting from webvtt using regex
我正在尝试构建一个在 .Net 环境中使用的正则表达式,它允许我从 webvtt 文件中提取信息。
我想从可能是字幕或其他内容的下一行中提取时间码信息和相应信息。
我遇到 运行 的问题是下一行的信息有时是一行,有时跨越多行,例如:
00:00:02.736 --> 00:00:06.072 line:79.33% position:10.00% align:start
AND YOUR GRACE?
00:00:06.072 --> 00:00:08.875 line:74.00% position:10.00% align:start
WHAT WILL YOU DO
ABOUT THAT?
而且我需要确保我得到了所有内容,而不会无意中 运行进入下一组的开头。
我试过这个:
\n(\d{2}:\d{2}:\d{2}.\d{3})(.|\n)*(?<!\d{2}:\d{2}:\d{2}.\d{3})
想法是它获取第一个时间码和之后的所有内容,但在下一次出现第一个时间码时再次停止,但它捕获了整个文件。
我也试过:
(?<!WEBVTT)(\d{2}:\d{2}:\d{2}.\d{3}).*?(\d{2}:\d{2}:\d{2}.\d{3}).*\n([^\n]+\n)*[^\n]+
我意识到负先行在一开始是多余的。在这里,我试图将时间码放入单独的组中,忽略该行的其余部分,然后从新行开始捕获所有内容,但这是跳过字幕文本而不是跨越多行。
我似乎遇到的问题是我捕获的行太多,或者不够。
有没有办法让正则表达式匹配某些内容(例如第一个时间码)及其后的所有内容,然后在第一个匹配项命中时重新开始?
我确信这一定是可能的,但我是使用正则表达式的新手,所以我发现这很难。我不介意是否必须将其分解为多个操作才能获得所需的结果。
所以我想要得到的是:
第一组:
00:00:02.736
或
00:00:02.736 --> 00:00:06.072
第二个(或第三个取决于以上):
AND YOUR GRACE?
然后:
00:00:06.072 --> 00:00:08.875
其次是:
WHAT WILL YOU DO
ABOUT THAT?
等等
看来你可以使用
(?m)^(\d{2}:\d{2}:\d{2}\.\d+) +--> +(\d{2}:\d{2}:\d{2}\.\d+).*[\r\n]+\s*(?s)((?:(?!\r?\n\r?\n).)*)
详情
(?m)
- 开启多行模式
^
- 行首(由于 (?m)
)
(\d{2}:\d{2}:\d{2}\.\d+)
- 第 1 组:时间戳模式
+--> +
- 1+ 个空格,-->
,1+ 个空格
(\d{2}:\d{2}:\d{2}\.\d+)
- 第 2 组:时间戳模式
.*[\r\n]+\s*
- 行的其余部分 (.*
),1+ 个换行符 ([\r\n]+
),然后是 0+ 个空格 (\s*
)
(?s)
- 从现在开始启用 DOTALL(.
匹配换行符)
((?:(?!\r?\n\r?\n).)*)
- 第 3 组:任何未开始双换行序列的字符,0+ 次。
我正在尝试构建一个在 .Net 环境中使用的正则表达式,它允许我从 webvtt 文件中提取信息。
我想从可能是字幕或其他内容的下一行中提取时间码信息和相应信息。 我遇到 运行 的问题是下一行的信息有时是一行,有时跨越多行,例如:
00:00:02.736 --> 00:00:06.072 line:79.33% position:10.00% align:start
AND YOUR GRACE?
00:00:06.072 --> 00:00:08.875 line:74.00% position:10.00% align:start
WHAT WILL YOU DO
ABOUT THAT?
而且我需要确保我得到了所有内容,而不会无意中 运行进入下一组的开头。
我试过这个:
\n(\d{2}:\d{2}:\d{2}.\d{3})(.|\n)*(?<!\d{2}:\d{2}:\d{2}.\d{3})
想法是它获取第一个时间码和之后的所有内容,但在下一次出现第一个时间码时再次停止,但它捕获了整个文件。
我也试过:
(?<!WEBVTT)(\d{2}:\d{2}:\d{2}.\d{3}).*?(\d{2}:\d{2}:\d{2}.\d{3}).*\n([^\n]+\n)*[^\n]+
我意识到负先行在一开始是多余的。在这里,我试图将时间码放入单独的组中,忽略该行的其余部分,然后从新行开始捕获所有内容,但这是跳过字幕文本而不是跨越多行。
我似乎遇到的问题是我捕获的行太多,或者不够。
有没有办法让正则表达式匹配某些内容(例如第一个时间码)及其后的所有内容,然后在第一个匹配项命中时重新开始?
我确信这一定是可能的,但我是使用正则表达式的新手,所以我发现这很难。我不介意是否必须将其分解为多个操作才能获得所需的结果。
所以我想要得到的是:
第一组:
00:00:02.736
或
00:00:02.736 --> 00:00:06.072
第二个(或第三个取决于以上):
AND YOUR GRACE?
然后:
00:00:06.072 --> 00:00:08.875
其次是:
WHAT WILL YOU DO
ABOUT THAT?
等等
看来你可以使用
(?m)^(\d{2}:\d{2}:\d{2}\.\d+) +--> +(\d{2}:\d{2}:\d{2}\.\d+).*[\r\n]+\s*(?s)((?:(?!\r?\n\r?\n).)*)
详情
(?m)
- 开启多行模式^
- 行首(由于(?m)
)(\d{2}:\d{2}:\d{2}\.\d+)
- 第 1 组:时间戳模式+--> +
- 1+ 个空格,-->
,1+ 个空格(\d{2}:\d{2}:\d{2}\.\d+)
- 第 2 组:时间戳模式.*[\r\n]+\s*
- 行的其余部分 (.*
),1+ 个换行符 ([\r\n]+
),然后是 0+ 个空格 (\s*
)(?s)
- 从现在开始启用 DOTALL(.
匹配换行符)((?:(?!\r?\n\r?\n).)*)
- 第 3 组:任何未开始双换行序列的字符,0+ 次。