我正在尝试将我在Video::Filename Perl模块中找到的以下Perl正则表达式转换为Python 2.5.4正则表达式来解析文件名
# 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中知道命名组的正则表达式扩展是不同的,但我对语法不是100%肯定。
这就是我的尝试:
# 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>[^\/]+?))?$')
我不知道从哪里开始寻找。
答案 0 :(得分:6)
您的翻译有两个问题。首先,第二次提到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
引用后编辑是条件表达式,并正确翻译反向引用)。
答案 1 :(得分:2)
我找到了令人讨厌的部分,但是如果不把整个事情包裹起来,就无法弄清楚到底出了什么问题。
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>)\]) // this part here causes the error message
(?:[\s._-]*(?P<epname>[^\/]+?))?$')
问题似乎在于python中的组名必须是有效的python标识符(check documentation)。括号似乎是问题所在。删除它们
(?(P<openb>)\]) //with parentheses
(?P<openb>\]) //without parentheses
redefinition of group name 'openb' as group 6; was group 2
答案 2 :(得分:0)
那些正面试图是生病扭曲的心灵的产物......: - )
无论如何,(?())是Python和Perl中的条件,并且上面的perl语法看起来应该与Python语法相同,即它评估为名为exists的组的true。
从哪里开始寻找?这些模块的文档在这里:
http://docs.python.org/library/re.html http://www.perl.com/doc/manual/html/pod/perlre.html
答案 3 :(得分:0)
我可能错了,但您尝试使用以下方法进行反向引用:
(?:\k<season>x)
Python中的语法\g<name>
不是吗?