【问题标题】:Regex : Match the two closest strings with only one occurence of another string between them正则表达式:匹配两个最接近的字符串,它们之间仅出现另一个字符串
【发布时间】:2021-04-11 21:19:47
【问题描述】:

我想做两行的非贪婪匹配,但只包括它们之间出现的另一行。

让我用 ffprobe 的日志来说明这一点:

[FRAME]
media_type=video
stream_index=1
pict_type=P
coded_picture_number=1
display_picture_number=0
[/FRAME]
[FRAME]
media_type=video
stream_index=1
pict_type=B
coded_picture_number=1
display_picture_number=0
[/FRAME]
[FRAME]
media_type=video
stream_index=1
pict_type=P
coded_picture_number=1
display_picture_number=0
[/FRAME]
[FRAME]
media_type=video
stream_index=1
pict_type=I
coded_picture_number=1
display_picture_number=0
[/FRAME]
[FRAME]
media_type=video
stream_index=1
pict_type=P
coded_picture_number=1
display_picture_number=0
[/FRAME]
[FRAME]
media_type=video
stream_index=1
pict_type=I
coded_picture_number=1
display_picture_number=0
[/FRAME]

此日志由视频帧组成。帧以 [FRAME] 开始,以 [/FRAME] 结束。

我想在下一帧中匹配一个 pict_type=B 紧跟其后的 pict_type=I。

显然pict_type=B.*?pict_type=I 在这里不起作用,它会匹配 B P I

我试图将 [/FRAME] 的出现限制为仅 1 次

pict_type=B(.*?[^\[\/FRAME\]]{1})pict_type=I

但它匹配两个 [/FRAME] 只是为了达到 pict_type=I

而且每个视频都有不同的行数,所以用 \r\n 重复做正则表达式行是没有用的

我做错了什么,如何告诉它在我的两个 pict_type 之间只允许一个 [/FRAME] ?

【问题讨论】:

  • 这取决于您希望匹配/模式的具体程度。在匹配下一个 pict_type= 之前,您应该防止交叉匹配 [FRAME] 我认为这种模式会给您匹配 regex101.com/r/49VQlK/1
  • 嗯,这个模式匹配一​​切,也许是因为它很贪心。实际上我只想穿过 [/FRAME] 和 [FRAME] 一次。 B 帧的结束帧和 I 帧的开始。但我想排除一个或两个应该是相同的。
  • 这里的模式regex101.com/r/o7AgcX/1[/FRAME] and [FRAME] only once 交叉对吗?它得到预期的匹配吗? (请注意,您不应使用s 标志使点匹配换行符)
  • 哦,是的,它完全符合我在 regex101 中想要的内容!但是为什么在 Notepad++ 中我得到 0 match ?我禁用与新行匹配的点。 Notepad++ 没有所有的标志设置?
  • @Thefourthbird 好吧,我想通了!我必须删除您的行的第一个 / 以及最后的 /g。你能解释一下他们在这条线上的角色吗?

标签: regex


【解决方案1】:

您可以使用与开头 [FRAME] 和结尾 [/FRAME] 匹配的模式,同时匹配第一个 pict_type=B 然后在下一帧中匹配第二个 pict_type=I 不使用负前瞻 (?! 越过这些边界/p>

\[FRAME](?:\R(?!\[/?FRAME]|pict_type).*)*+\Rpict_type=B(?:\R(?!\[/?FRAME]|pict_type).*)*+\R\[/FRAME]\R\[FRAME](?:\R(?!\[/?FRAME]|pict_type).*)*+\Rpict_type=I(?:\R(?!\[/?FRAME]|pict_type).*)*+\R\[/FRAME]

模式匹配:

  • \[FRAME]匹配[FRAME]
  • (?:\R(?!\[/?FRAME]|pict_type).*)*+ 使用possessive quantifier *+ 匹配所有不以[FRAME][/FRAME]pict_type 开头的行
  • \Rpict_type=B 匹配换行符和 pict_type=B
  • (?:\R(?!\[/?FRAME]|pict_type).*)*+ 匹配所有不以[FRAME][/FRAME]pict_type 开头的行
  • \R\[/FRAME] 匹配换行符并匹配结束 [/FRAME]
  • \R\[FRAME] 匹配换行符并匹配第二个 [FRAME]
  • (?:\R(?!\[/?FRAME]|pict_type).*)*+ 匹配所有不以[FRAME][/FRAME]pict_type 开头的行
  • \Rpict_type=I 匹配换行符并匹配 pict_type=I
  • (?:\R(?!\[/?FRAME]|pict_type).*)*+ 匹配所有不以[FRAME][/FRAME]pict_type 开头的行
  • \R\[/FRAME] 匹配换行符并匹配 [/FRAME]

Regex demo

【讨论】:

  • 非常感谢这些解释!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多