Python 3 regex 如何正确使用分组?

Posted

技术标签:

【中文标题】Python 3 regex 如何正确使用分组?【英文标题】:Python 3 regex How to use grouping properly? 【发布时间】:2016-10-02 18:18:51 【问题描述】:

编辑:对不起,我只允许插入 2 个链接,其他链接在这里是纯文本。

嗨 我对 Python 和正则表达式非常陌生。我在 regex101 和许多其他网站上搜索了如何正确使用它,但它不起作用,我不知道该怎么办了。

我家里有一些 IP 摄像机,它们通过 ftp 发送图片。 它们的名称类似于(我从字符串中删除了 MAC 和序列号):

image_20130225_175225_9.jpg AABBCCDDEEFF(UserNameOfCam)_0_20150905215835_0.jpg 112233445566(0000serial)_0_20130625223148_1337167.jpg 012345-6789ABCDEF01-234567_20160724_180030.jpg AA_BB_CC_DD_EE_FF_OPI-012345-QWERT_0_20130724133101_8.jpg

为了每天释放一次空间,所有这些 jpeg 图片将通过 mencoder 转换为带有批处理文件的 mp4(Windows)。这已经在工作,但图像中没有刻录时间信息。这只是一张没有 OSD 的普通图片。

所以我尝试制作一个 .srt 文件以在视频播放器中将时间和日期显示为字幕。因为我刚在学校学习 C,所以我硬编码了一种丑陋的方式来生成它,查看每个文件名并手动搜索字符串中的哪个部分决定了每个凸轮,例如第一个凸轮总是以“image_”开头,第二个是凸轮名称,第三个是文件名中的序列号,依此类推。

看起来是这样的:

if(strstr(temp_line, "image"))  //for the first cam
         do extracting info 
else if(strstr(temp_line, "(UserNameOfCam)_")) //for the second
         do extracting info 
else if(...

它非常不灵活,如果我想重命名第二个凸轮,我必须在 C 中手动更改 srt 生成器的源代码,并且每次都重新编译它。

然后我想“见鬼,让我们试试 Python,它是为这样的脚本编写的”,经过几天和几个小时的编程和谷歌搜索,我编写了脚本。然后我想用正则表达式来做,因为它非常适合。

由于我是初学者,我使用debuggex来可视化正则表达式的制作和pythex进行匹配。到目前为止,它可以识别第一台相机,我很高兴:) 但是经过几个小时的尝试让它识别超过 1 个模式后,我不知道我做错了什么。我尝试了 \g (?P= 和许多其他方法,但没有一个有效。我做的事情完全错误,不知道是什么。

这是第一个凸轮的图案

www.debuggex.com/r/kvd5IZc760Z-cZmz

Here is the matching of the first cam

这是前两个凸轮的不工作尝试

www.debuggex.com/r/C0TwsxHS9QZoXIFc

如果需要,这里是制作 srt 的 Python 脚本。

pastebin.com/kZPQnu9T

任何提示或建议如何使它工作,或者我在哪里做了错误的步骤?

EDIT2:我忘了提到我需要从正则表达式中提取的信息,因为时间和日期存储在文件名中。

EDIT3:感谢您的回复。我认为将所有内容放在一个正则表达式中会使其更快,因为它必须解析多达 100k 行。我还尝试从正则表达式中提取信息,因为可以将模式命名为“年”之类的组。年份信息总是相同的,所以我想,最好制作一次年份模式,并在需要时重复使用它,然后提取也被处理......虽然它不是那样工作的。它可以从第一个凸轮中提取所有有用的信息,但是如果我尝试重用第一个凸轮的模式,我不会得到第二个匹配的任何信息。 “(?P=year)” 行不匹配,如果我用与第一个凸轮相同的行替换它,则会出现错误,因为年份组现在翻了一番。虽然如果我删除了第一个凸轮的整个图案,它就可以工作。

【问题讨论】:

欢迎来到 SO。这个问题真正需要的是一个 mcve。请参阅***.com/help/mcve 这意味着从一个空文件开始并创建一个完整的 python 程序来显示正则表达式的问题,同时删除所有其他有效的东西,比如转换为 mp4。然后将那个简短的 python 文件粘贴到问题中(不要链接)。然后我们可以查看它,甚至下载并测试它。这样你会得到更好的答案。 “我认为将所有内容放在一个正则表达式中会更快,因为它必须解析多达 100k 行。” - 不要过早优化(因为它是万恶之源)。实施最简单的可行解决方案,然后,如果速度太慢,请尝试找到更快的解决方案。 【参考方案1】:

您不需要制作一个匹配所有内容的巨大正则表达式。最好制作几个与特定相机匹配的较小的正则表达式。

因此,如果您想以相同的方式处理摄像头 1 和摄像头 2,您的代码可能看起来像这样。

import re

cam1 = re.compile(r'some regex')
cam2 = re.compile(r'something else')

if cam1.match(filename) and cam2.match(filename):
    process_data()

此外,如果您想从正则表达式中提取信息,您只需要分组。否则分组并不是真正需要的(除非你想让正则表达式更清晰)。

【讨论】:

嗯好的。也许这是让它尽快工作的最好情况,给每个凸轮一个自己的正则表达式。只是为了我的理解:是否可以在其他组中重用组?甚至可以将所有 cam 解析放在一个正则表达式中吗? 可以构建一个巨大的正则表达式。但不是我推荐的东西。对于自己和他人来说,理解起来变得更加困难。正如您已经发现的那样,调试变得更加困难。您可以在其他正则表达式中重用正则表达式的一部分。它只是字符串。

以上是关于Python 3 regex 如何正确使用分组?的主要内容,如果未能解决你的问题,请参考以下文章

python常用模块之——正则re模块

2019-1-17 python正则表达式

PythonPycharm Regex matches

如何使 RegEx 查询仅匹配整个字符串?

如何在 pymongo 中正确设计正则表达式?

如何在 C++ 中对多个正则表达式使用正则表达式“分组”?