You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用正则提取Usenet主题中含嵌套[]的类文件名

Usenet主题中含嵌套方括号的文件名提取方案

问题背景

原正则表达式r"([\w\-+()'\s.,]{5,}\.[A-Za-z0-9]{2,4})[^A-Za-z0-9]"能较好提取Usenet主题中的类文件名,但遇到文件名含嵌套[]且自身被[]包裹的场景时失效。例如输入:

[Text]-[Text]-[Filename[Uploader].txt]-[1/23] - "" yEnc 1234567890 (1/23456)

需要提取Filename[Uploader].txt,直接将[]加入字符组会误匹配外层括号,需调整正则逻辑。

补充测试用例(输入→预期输出):

test_cases = [
    ('Subject-KrzpfTest [02/30] - ""KrzpfTest.part.nzb"" yEnc', "KrzpfTest.part.nzb"),
    ('[PRiVATE]-[WtFnZb]-[Supertje-_S03E11-12_-blabla_+_blabla_WEBDL-480p.mkv]-[4/12] - "" yEnc 9786 (1/1366)', "Supertje-_S03E11-12_-blabla_+_blabla_WEBDL-480p.mkv"),
    ('[N3wZ] MAlXD245333\\::[PRiVATE]-[WtFnZb]-[Show.S04E04.720p.AMZN.WEBRip.x264-GalaxyTV.mkv]-[1/2] - "" yEnc  293197257 (1/573)', "Show.S04E04.720p.AMZN.WEBRip.x264-GalaxyTV.mkv"),
    ("Singer - A Album (2005) - [04/25] - 02 Sweetest Somebody (I Know).flac", "Singer - A Album (2005) - [04/25] - 02 Sweetest Somebody (I Know).flac"),
    ('[PRiVATE]-[WtFnZb]-[00000.clpi]-[1/46] - "" yEnc  788 (1/1)', "00000.clpi"),
    ("[PRiVATE]-[WtFnZb]-[/More.Bla.S02E01.1080p.WEB.h264-EDITH[eztv.re].mkv] yEnc  2990558544 (1/4173)", "More.Bla.S02E01.1080p.WEB.h264-EDITH[eztv.re].mkv")
]

解决方案

针对嵌套方括号场景,使用支持嵌套匹配的正则表达式,同时排除分卷标记(如[1/23])的干扰:

适配Python 3.10+(支持无限嵌套)

import re

# 支持任意深度嵌套[]的正则
pattern = re.compile(r'''
    (?:\[)?  # 匹配可选的外层左括号
    (
        (?:
            [^\[\]]+          # 匹配非括号字符
            |
            \[ (?R) \]        # 递归匹配嵌套的[]结构
        )+?                   # 非贪婪匹配,避免过度延伸
        \.[A-Za-z0-9]{2,4}    # 匹配文件名扩展名(2-4位)
    )
    (?:\])?  # 匹配可选的外层右括号
    (?! \d+/\d+ )  # 排除后面跟着分卷标记(如1/23)的情况
''', re.VERBOSE)

适配低版本Python(支持两层嵌套)

如果使用Python 3.10以下版本,可使用非递归模式适配常见的两层嵌套场景:

pattern = re.compile(r'''
    (?:\[)?
    (
        (?:
            [^\[\]]+
            |
            \[
            (?:
                [^\[\]]+
                |
                \[ [^\[\]]* \]
            )*
            \]
        )+?
        \.[A-Za-z0-9]{2,4}
    )
    (?:\])?
    (?! \d+/\d+ )
''', re.VERBOSE)

测试验证

将测试用例代入验证,代码如下:

for input_str, expected in test_cases:
    match = pattern.search(input_str)
    if match:
        # 处理部分文件名开头的多余斜杠
        result = match.group(1).lstrip('/')
        assert result == expected, f"匹配失败:提取结果{result}≠预期{expected}"
print("所有测试用例验证通过")

逻辑说明

  1. 嵌套括号处理:通过递归((?R))或分层匹配,识别文件名内部的嵌套[],避免误匹配外层括号;
  2. 扩展名约束:保留原正则对扩展名的匹配规则,确保提取内容为类文件名;
  3. 分卷标记排除:通过负向预测(?! \d+/\d+ ),避免将[1/23]这类分卷标记误识别为文件名;
  4. 兼容性:提供低版本Python的替代方案,覆盖常见嵌套场景。

内容的提问来源于stack exchange,提问作者Safihre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 18:34:50