我正在尝试将Video::Filenameperl模块中找到的以下perl regex转换为python 2.5.4 regex来解析文件名

# Perl > v5.10
re => '^(?:(?<name>.*?)[\/\s._-]*)?(?<openb>\[)?(?<season>\d{1,2})[x\/](?<episode>\d{1,2})(?:-(?:\k<season>x)?(?<endep>\d{1,2}))?(?(<openb>)\])(?:[\s._-]*(?<epname>[^\/]+?))?$',

我也想使用命名组,而且我知道在Python中,命名组的regex扩展是不同的,但是我不能百分之百确定语法。
我就是这么想的:
# Python (not working)
r = re.compile(r'^(?:(?P<name>.*?)[\/\s._-]*)?(?P<openb>\[)?(?P<season>\d{1,2})[x\/](?P<episode>\d{1,2})(?:-(?:\kP<season>x)?(?P<endep>\d{1,2}))?(?(P<openb>)\])(?:[\s._-]*(?P<epname>[^\/]+?))?$')

我得到的错误是:
   raise error, v # invalid expression
sre_constants.error: bad character in group name

例如,我成功地转换了这一个,它工作了。但上面的那个我好像不太对劲我在Python中得到一个编译错误。
# Perl:
re => '^(?:(?<name>.*?)[\/\s._-]+)?(?:s|se|season|series)[\s._-]?(?<season>\d{1,2})[x\/\s._-]*(?:e|ep|episode|[\/\s._-]+)[\s._-]?(?<episode>\d{1,2})(?:-?(?:(?:e|ep)[\s._]*)?(?<endep>\d{1,2}))?(?:[\s._]?(?:p|part)[\s._]?(?<part>\d+))?(?<subep>[a-z])?(?:[\/\s._-]*(?<epname>[^\/]+?))?$',

# Python (working):
r = re.compile(r'^(?:(?P<name>.*?)[\/\s._-]+)?(?:s|se|season|series)[\s._-]?(?P<season>\d{1,2})[x\/\s._-]*(?:e|ep|episode|[\/\s._-]+)[\s._-]?(?P<episode>\d{1,2})(?:-?(?:(?:e|ep)[\s._]*)?(?P<endep>\d{1,2}))?(?:[\s._]?(?:p|part)[\s._]?(?P<part>\d+))?(?P<subep>[a-z])?(?:[\/\s._-]*(?P<epname>[^\/]+?))?$')

我不知道从哪里开始找。

最佳答案

你的翻译有两个问题。首先,第二个提到的openb在其周围有额外的括号,使其成为conditional expression,而不是命名表达式。
接下来是,您没有翻译\k<season>backreference,python使用(P=season)来匹配。以下为我编译:

r = re.compile(r'^(?:(?P<name>.*?)[\/\s._-]*)?(?P<openb>\[)?(?P<season>\d{1,2})[x\/](?P<episode>\d{1,2})(?:-(?:(?P=season)x)?(?P<endep>\d{1,2}))?(?(openb)\])(?:[\s._-]*(?P<epname>[^\/]+?))?$')

如果我是您,我将使用re.verbose将此表达式拆分成多行,并添加大量文档,以便在将来需要保持可维护性的情况下继续理解该表达式。
(在实现第二个openb引用是一个条件表达式并正确翻译后向引用后编辑)。

10-04 11:12
查看更多