python 是否有办法通过www.example.com查找(可能)多个结果re.search?

qcbq4gxm  于 2023-02-18  发布在  Python
关注(0)|答案(3)|浏览(136)

在解析电视节目的文件名时,我想提取关于它们的信息来用于重命名。我有一个工作模型,但它目前使用28个if/elif语句来处理我在过去几年中看到的每个文件名迭代。我希望能够将其浓缩为我不感到羞耻的东西,所以任何帮助都将不胜感激。
第一阶段的代码悔改是希望抓住多个集数。我已经得到了下面的代码,但在第一个条目中,它只显示第一个集数,而不是所有三个。

import re

def main():
    pattern = '(.*)\.S(\d+)[E(\d+)]+'
    strings = ['blah.s01e01e02e03', 'foo.s09e09', 'bar.s05e05']

    #print(strings)
    for string in strings:
        print(string)
        result = re.search("(.*)\.S(\d+)[E(\d+)]+", string, re.IGNORECASE)
        print(result.group(2))

if __name__== "__main__":
    main()

这将输出:

blah.s01e01e02e03
01
foo.s09e09
09
bar.s05e05
05

这可能是微不足道的,但是大多数情况下正则表达式也可能是楔形文字。

r8xiu3jd

r8xiu3jd1#

re.findall而不是re.search将返回所有匹配项的列表

q7solyqu

q7solyqu2#

不可以。你可以使用findall来查找所有的e\d+,但是它不能找到重叠的匹配项,这使得不可能将s\d+与它一起使用(也就是说,你不能区分"foo.s01e006e007“中的e02"age007.s01e001"中的e02),而且Python不允许你使用可变长度的lookbehind(以确保s\d+在它之前而没有重叠)。
这样做的方法是找到\.s\d+((?:e\d+)+)$,然后在另一个步骤中分裂得到的组1(无论是通过使用findalle\d+,还是通过使用(?<!^)(?=e)分裂)。

text = 'blah.s01e01e02e03'
match = re.search(r'\.(s\d+)((?:e\d+)+)$', text, re.I)
season = match.group(1)
episodes = re.findall(r'e\d+', match.group(2), re.I)
print(season, episodes)
# => s01 ['e01', 'e02', 'e03']
slwdgvem

slwdgvem3#

如果可以使用PyPi regex module,那么可以在模式中使用重复捕获组,然后使用.captures()
例如:

import regex

s = "blah.s01e01e02e03"
pattern = r"\.(s\d+)(e\d+)+"
m = regex.search(pattern, s, regex.IGNORECASE)
if m:
    print(m.captures(1)[0], m.captures(2))

输出:

s01 ['e01', 'e02', 'e03']

参见Python演示和regex101 demo
或者对命名的捕获组使用.capturesdict ()
例如:

import regex

s = "blah.s01e01e02e03"
pattern = r"\.(?P<season>s\d+)(?P<episodes>e\d+)+"
m = regex.search(pattern, s, regex.IGNORECASE)
if m:
    print(m.capturesdict())

输出:

{'season': ['s01'], 'episodes': ['e01', 'e02', 'e03']}

参见Python演示。

    • 注意**您使用的符号[E(\d+)]character class,它匹配1或列出的字符,如E(数字+)

相关问题