由于您正在进行数据提取,我将使用这个简单的正则表达式:
^(?=.*start:)(?=.*bitrate:).*Duration: ([\d.:]+)
时间戳可以在第一个捕获组中找到。
数据似乎是从程序日志生成的,所以我假设间距是规则的。我的正则表达式将忽略源字符串中的start
,bitrate
和的顺序。Duration
如果您想要不区分大小写的匹配,请打开该标志。
忽略排序将使正则表达式在长字符串上变慢。我们拥有的假设越多(尤其是关于排序的假设),正则表达式就越好。
解释
^
(?=.*start:)
(?=.*bitrate:)
.*Duration: ([\d.:]+)
^
锚定字符串的开头。我出于性能原因添加了这个,因为如果正则表达式引擎已经详尽地回溯了所有案例并且没有找到匹配项,则无需检查匹配项。
(?=.*start:)
零宽度正前瞻。它将尝试.*start:
从字符串中的当前位置匹配,如果找到则从它离开的位置继续匹配,如果没有找到则停止。它被称为零宽度,因为它实际上并不消耗字符串,而不是正则表达式的这一部分.*Duration: ([\d.:]+)
。
(?=.*bitrate:)
,和上面一样,检查bitrate:
字符串中是否有前面。
.*Duration: ([\d.:]+)
与实际时长相符。我不关心格式,因为我假设你得到的任何东西都是正确的,所以我只抓住最长的数字序列\d
,.
和:
.
当字符串中有多个匹配项时,使用字符的概念很重要。有时,您想在决定操作之前检查字符串是否包含某个序列。这样的检查不应该消耗 character,因为当您还没有处理当前位置的文本时,您不应该处理前面的文本。如果您使用文本,那么您可能会丢失文本中从当前位置到字符串中前面的文本的一些匹配项。