【问题标题】:Trying to return "basenames" of filenames with and without version tags尝试返回带有和不带有版本标签的文件名的“基本名称”
【发布时间】:2017-12-04 21:20:32
【问题描述】:

我一直在尝试编写一个正则表达式,它将返回版本化文件的基本名称,但也会返回同一列表中非版本化文件的基本名称。

import re

file_list = [
    "ThisFile_v01.ext",
    "ThisFile_v02.ext",
    "ThatFile_v01.ext",
    "ThatFile_v02.ext",
    "NonVersionedFile.ext",
    "Non_VersionedFile.ext",
]

r = re.compile(r"^(?P<basename>.*(?!_v))(?P<version>_v\d+\.)?(?(version).*$|\..*$)")
for f in file_list:
    match = r.match(f)
    print(match.group('basename'))

我正在尝试返回这样的列表:

ThisFile
ThisFile
ThatFile
ThatFile
NonVersionedFile
Non_VersionedFile

我目前得到这个:

ThisFile_v01
ThisFile_v02
ThatFile_v01
ThatFile_v02
NonVersionedFile
Non_VersionedFile

我可能想多了,但我已经经历了很多次迭代,我似乎无法弄清楚这一点。任何帮助将不胜感激。

【问题讨论】:

    标签: python regex regex-negation regex-lookarounds regex-group


    【解决方案1】:

    你的正则表达式让我有点头疼。我想所有可选部分之间都存在冲突。

    为什么不直接删除v_xxx(可选)和使用sub 的扩展?

    r = re.compile("(_v\d+)?(\..*)")
    for f in file_list:
        print(r.sub("",f))
    

    这更简单,给了我:

    ThisFile
    ThisFile
    ThatFile
    ThatFile
    NonVersionedFile
    Non_VersionedFile
    

    【讨论】:

    • 是的,我完全想多了。谢谢!
    【解决方案2】:

    对正则表达式的超级简单更改可以解决您的问题。您的正则表达式的根本问题是您使用的是“贪婪”调用。如果你告诉他们“不贪婪”,你会得到你想要的输出。

    r = re.compile(r"^(?P&lt;basename&gt;.*?)(?P&lt;version&gt;_v[0-9]+)?\.ext")

    上面的正则表达式强制基本名称搜索最小化(组末尾的? 是导致这种情况的原因),这意味着.* 将尽快停止搜索,而不是吞噬它可以搜索的每个字符动手吧。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-02
      • 1970-01-01
      • 2015-03-14
      • 2012-04-22
      • 1970-01-01
      • 2017-05-07
      • 2016-12-09
      相关资源
      最近更新 更多