首页 > 解决方案 > 如何使用正则表达式捕获多行文件中的最后一组?

问题描述

我正在尝试使用正则表达式来获取部分字幕文件。它们采用以下格式:

1
00:00:38,505 --> 00:00:40,438
<i>I'm not gonna bullshit you.</i>

...

1029
01:37:20,223 --> 01:37:23,023
No thanks.

文本可以占据多行。

这是我目前正在使用的:

(\d+?)\r\n(\d+?):(\d+?):(\d+?),(\d+?) --> (\d+?):(\d+?):(\d+?),(\d+?)\r\n(?<content>(.+)(\r\n)*\D*)[\r\n|$]*?

它正确捕获了所有组,但忽略了最后一场比赛。因此,如果文本文件中有 1029 个字幕,它会找到其中的 1028 个。该文件在我提供的示例中的 </i> 之后结束。这是唯一未被捕获的群体。

谁能帮我这个?我认为由于没有将“$”指定为多行,因此“$”将充当“文件结尾”,但我似乎错了。

标签: regex

解决方案


您可以使用

(?sm)^(\d+)\r?\n(\d+?):(\d+):(\d+),(\d+) --> (\d+):(\d+):(\d+),(\d+)\r?\n(?<content>.*?)(?=\r?\n\d+\r?$|\z)

请参阅正则表达式演示

细节

  • (?sm)- 在每行的开头和结尾启用锚点匹配(with m)和点匹配换行符(with s
  • ^- 一行的开始
  • (\d+)- 第一组:一位或多位数字
  • \r?\n- CRLF 或 LF 结尾
  • (\d+):(\d+):(\d+),(\d+) --> (\d+):(\d+):(\d+),(\d+)- 1+ 位 (Group 2), :, 1+ 位 (Group 3), :, 1+ 位 (Group 4), ,, 1+ 位 (Group 5),-->用 1 个空格括起来, 1+ 位 (Group 6), :, 1+ 位(第 7 组), :, 1+ 位(第 8 组), ,, 1+ 位(第 9 组)
  • \r?\n- CRLF 或 LF 结尾
  • (?<content>.*?)- 将匹配任何 0+ 个字符的“内容”分组,尽可能少到第一个
  • (?=\r?\n\d+\r?$|\z)- CRLF 或 LF 结尾,1+ 位数字和行尾或字符串结尾。

C#代码片段:

var matches = Regex.Matches(text, @"(?sm)^(\d+)\r?\n(\d+?):(\d+):(\d+),(\d+) --> (\d+):(\d+):(\d+),(\d+)\r?\n(?<content>.*?)(?=\r?\n\d+\r?$|\z)");

推荐阅读