有一种方法,以匹配的图案(e\d\d)几次,捕获每一个成一组?例如,给定字符串..

blah.s01e24e25

..我希望得到四组:

1 -> blah
2 -> 01
3 -> 24
4 -> 25

在明显的正则表达式使用是(在Python正则表达式:

import re
re.match("(\w+).s(\d+)e(\d+)e(\d+)", "blah.s01e24e25").groups()

..但我也想匹配下面的任一:

blah.s01e24
blah.s01e24e25e26

您似乎无法做到(e\d\d)+,或者说你可以,但它只是抓住了最后一次出现:

>>> re.match("(\w+).s(\d+)(e\d\d){2}", "blah.s01e24e25e26").groups()
('blah', '01', 'e25')
>>> re.match("(\w+).s(\d+)(e\d\d){3}", "blah.s01e24e25e26").groups()
('blah', '01', 'e26')

我想这样做在一个单一的正则表达式,因为我有多种模式相匹配的电视节目的文件名,并且不希望复制每个表达式来处理多个事件:

\w+\.s(\d+)\.e(\d+) # matches blah.s01e01
\w+\.s(\d+)\.e(\d+)\.e(\d+) # matches blah.s01e01e02
\w+\.s(\d+)\.e(\d+)\.e(\d+)\.e(\d+) # matches blah.s01e01e02e03

\w - \d+x\d+ # matches blah - 01x01
\w - \d+x\d+\d+ # matches blah - 01x01x02
\w - \d+x\d+\d+\d+ # matches blah - 01x01x02x03

..等众多其它图案。

另一件事情复杂化 - 我想这些regexs存储在配置文件中,所以使用的解决方案多regexs和函数调用是不希望的 - 但是,如果这被证明是不可能的我就允许用户添加简单regexs

基本上,有一个方法使用正则表达式来捕获的重复图案?

有帮助吗?

解决方案 4

在思考的问题后,我想我有一个简单的解决方案,使用命名组。

用户(或I)可以用最简单的正则表达式是:

(\w+\).s(\d+)\.e(\d+)

的文件名解析类会第一组作为节目名称,第二季作为数,第三作为集数。这涵盖了大部分的文件。

我会允许这几个不同的命名组:

(?P<showname>\w+\).s(?P<seasonnumber>\d+)\.e(?P<episodenumber>\d+)

要支持多集,我会支持两个命名组,像startingepisodenumberendingepisodenumber支持之类的东西showname.s01e01-03

(?P<showname>\w+\)\.s(?P<seasonnumber>\d+)\.e(?P<startingepisodenumber>\d+)-(?P<endingepisodenumber>e\d+)

最后,允许命名组名字匹配episodenumber\d+episodenumber1episodenumber2等):

(?P<showname>\w+\)\.
s(?P<seasonnumber>\d+)\.
e(?P<episodenumber1>\d+)
e(?P<episodenumber2>\d+)
e(?P<episodenumber3>\d+)

但仍需要可能重复用于不同量e01s的模式,但绝不会有两个非连续的事件(如show.s01e01e03e04)的文件,所以使用starting/endingepisodenumber组应该解决这个问题,并为怪异的情况下,用户遇到,他们可以使用episodenumber\d+组名称

这并没有真正回答序列的图案的问题,但它解决了,导致我问这问题! (我还是会接受另一种答案,说明如何在一个正则表达式匹配s01e23e24...e27 - !如果有人工作了这一点)

其他提示

做的两个步骤,一是找到所有的数字,然后一个分裂他们:

import re

def get_pieces(s):
    # Error checking omitted!
    whole_match = re.search(r'\w+\.(s\d+(?:e\d+)+)', s)
    return re.findall(r'\d+', whole_match.group(1))

print get_pieces(r"blah.s01e01")
print get_pieces(r"blah.s01e01e02")
print get_pieces(r"blah.s01e01e02e03")

# prints:
# ['01', '01']
# ['01', '01', '02']
# ['01', '01', '02', '03']

捕获基团等于括号组的数量的数量。看看findallfinditer解决您的问题。

非分组括号:(?:asdfasdg)

不具有出现:(?:asdfasdf)?

c = re.compile(r"""(\w+).s(\d+)
                       (?:
                            e(\d+)
                            (?:
                                  e(\d+)
                            )?
                        )?
               """, re.X)

c = re.compile(r"""(\w+).s(\d+)(?:e(\d+)(?:e(\d+))?)?""", re.X)

也许这样的事情?

def episode_matcher(filename):
    m1= re.match(r"(?i)(.*?)\.s(\d+)((?:e\d+)+)", filename)
    if m1:
        m2= re.findall(r"\d+", m1.group(3))
        return m1.group(1), m1.group(2), m2
    # auto return None here

>>> episode_matcher("blah.s01e02")
('blah', '01', ['02'])
>>> episode_matcher("blah.S01e02E03")
('blah', '01', ['02', '03'])
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top