繁体   English   中英

正则表达式匹配特定单词上方最接近的标签(HLS 媒体播放列表)

[英]Regular expression to match closest tag above specific word (HLS media playlist)

给定一个 HLS 媒体播放列表,如下所示:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-ALLOW-CACHE:NO
#EXT-X-TARGETDURATION:7
#EXT-X-MEDIA-SEQUENCE:0

#EXT-X-PROGRAM-DATE-TIME:2022-09-12T10:03:22.621+02:00
#EXTINF:6.666666667,
seg1.ts
#EXT-X-PROGRAM-DATE-TIME:2022-09-12T10:03:29.637+02:00
#EXTINF:6.666666667,
seg2.ts
#EXT-X-PROGRAM-DATE-TIME:2022-09-12T10:03:36.583+02:00
#EXTINF:6.666666666,
seg3.ts

我想创建一个正则表达式来匹配最接近指定.ts 文件名的EXT-X-PROGRAM-DATE-TIME标记之后的日期时间。 例如,我希望能够通过指定匹配应以seg2.ts结尾来检索日期2022-09-12T10:03:29.637+02:00 即使将来在文件名和EXT-X-PROGRAM-DATE-TIME标签之间添加新标签,它也应该可以工作。

这个模式EXT-X-PROGRAM-DATE-TIME:(.*)[\s\S]*?seg2.ts )是我迄今为止的最大努力,但我不知道如何让比赛从最后可能的EXT-X-PROGRAM-DATE-TIME标记。 懒惰的量词没有帮助。 当前捕获的组是第一个EXT-X-PROGRAM-DATE-TIME之后的日期时间,即2022-09-12T10:03:22.621+02:00

我还研究了使用负前瞻,但我不知道如何将它与匹配seg2.ts之前的可变数量的字符和空格相结合。

我确信这已经在另一个上下文中得到了回答,但我只是找不到正确的搜索词。

您可能会编写不与以seg线开头的线相交的模式,然后匹配seg2.ts

^#EXT-X-PROGRAM-DATE-TIME:(.*)(?:\n(?!seg\d+\.ts$).*)*\nseg2\.ts$
  • ^字符串开头
  • #EXT-X-PROGRAM-DATE-TIME:逐字匹配
  • (.*)捕获组1 ,匹配该行的rest(注意这个也可以匹配一个空字符串)
  • (?:\n(?.seg\d+\.ts$).*)*匹配所有不以 seq 模式开头的行
  • \nseg2\.ts匹配换行符和seq2.ts
  • $字符串结尾

正则表达式演示

import re

pattern = r"^#EXT-X-PROGRAM-DATE-TIME:(.*)(?:\n(?!seg\d+\.ts$).*)*\nseg2\.ts$"

s = ("#EXTM3U\n"
            "#EXT-X-VERSION:3\n"
            "#EXT-X-ALLOW-CACHE:NO\n"
            "#EXT-X-TARGETDURATION:7\n"
            "#EXT-X-MEDIA-SEQUENCE:0\n\n"
            "#EXT-X-PROGRAM-DATE-TIME:2022-09-12T10:03:22.621+02:00\n"
            "#EXTINF:6.666666667,\n"
            "seg1.ts\n"
            "#EXT-X-PROGRAM-DATE-TIME:2022-09-12T10:03:29.637+02:00\n"
            "#EXTINF:6.666666667,\n"
            "seg2.ts\n"
            "#EXT-X-PROGRAM-DATE-TIME:2022-09-12T10:03:36.583+02:00\n"
            "#EXTINF:6.666666666,\n"
            "seg3.ts")

m = re.search(pattern, s, re.M)
if m:
    print(m.group(1))

Output

2022-09-12T10:03:29.637+02:00

如果您也不想交叉匹配其间的#EXT-X 部分,您可以添加它作为否定前瞻的替代方案:

^#EXT-X-PROGRAM-DATE-TIME:(.*)(?:\n(?!seg\d+\.ts\b|#EXT-X-PROGRAM-DATE-TIME:).*)*\nseg2\.ts$

我们可以在这里使用re.search和正则表达式调和点技巧:

#Python 2.7.17

import re

inp = """#EXTM3U
#EXT-X-VERSION:3
#EXT-X-ALLOW-CACHE:NO
#EXT-X-TARGETDURATION:7
#EXT-X-MEDIA-SEQUENCE:0

#EXT-X-PROGRAM-DATE-TIME:2022-09-12T10:03:22.621+02:00
#EXTINF:6.666666667,
seg1.ts
#EXT-X-PROGRAM-DATE-TIME:2022-09-12T10:03:29.637+02:00
#EXTINF:6.666666667,
seg2.ts
#EXT-X-PROGRAM-DATE-TIME:2022-09-12T10:03:36.583+02:00
#EXTINF:6.666666666,
seg3.ts"""

match = re.search(r'#EXT-X-PROGRAM-DATE-TIME:(\S+)(?:(?!EXT-X-PROGRAM-DATE-TIME).)*\bseg2\.ts', inp, flags=re.S)
if match:
    print(match.group(1))  # 2022-09-12T10:03:29.637+02:00

以下是正则表达式模式的解释:

  • #EXT-X-PROGRAM-DATE-TIME:
  • (\S+)匹配并捕获时间戳
  • (?:(?.EXT-X-PROGRAM-DATE-TIME).)*匹配所有内容而不跨越下一节
  • \bseg2\.ts匹配文件名(如果匹配):

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM