【问题标题】:Regex to catch the main name of a file正则表达式捕获文件的主要名称
【发布时间】:2018-04-26 07:56:42
【问题描述】:

我被困在正则表达式中,以在列表元素中捕获文件的主要名称。假设我有一个文件路径列表:

path_list = ['/Users/buggylines/histogram/offline-deployer-list_b7bacc7fdb-0e0e08077c_GERONIMO-2886_635_histogrambuglines_635.diff',
             '/Users/buggylines/histogram/normal.jsp_aa0c2c26dd-90188cc2a4_GERONIMO-4597_1293_histogrambuglines_1293.diff',
             '/Users/buggylines/histogram/hbase-env.sh_aa0c2c26dd-90188cc2a4_GERONIMO-4597_1293_histogrambuglines_1293.diff',
             '/Users/buggylines/histogram/LICENSE-tesh_cd1ec17e43-4ebc5e8021_GERONIMO-5702_1573_histogrambuglines_785.diff',
             '/Users/buggylines/histogram/geronimo_dcce59ae71-8f5c1aa7a1_GERONIMO-5661_1554_histogrambuglines_54.diff',
             '/Users/buggylines/histogram/catalina-6.0.18-G678601.jar.sha1_cd1ec17e43-4ebc5e8021_GERONIMO-5702_1573_histogrambuglines_785.diff',
             '/Users/buggylines/histogram/geronimo-naming-1.0.xsd_544dee5179-40a2ae1d41_GERONIMO-1027_131_histogrambuglines_131.diff',
             '/Users/buggylines/histogram/6.0.18-G678601.README.TXT_cd1ec17e43-4ebc5e8021_GERONIMO-5702_1573_histogrambuglines_785.diff'
            ]

我只想使用regex 捕获文件的名称。我需要以下输出:

expected_output = ['offline-deployer-list',
                   'normal.jsp',
                   'hbase-env.sh',
                   'LICENSE-tesh',
                   'geronimo',
                   'catalina-6.0.18-G678601.jar.sha1',
                   'geronimo-naming-1.0.xsd',
                   '6.0.18-G678601.README.TXT'
                  ]

这是我写的代码:

filename = []
for z, path in enumerate(path_list):
     pattern = re.search("((?:\w+[-]\w+[-]\w+|\w+[-]\w+|\w+)[.]\w+[_])|(?<=histogram/)(?:\w+[-]\w+[-]\D+[_]|\D+[-]\w+[_])|(?<=histogram\/)(\w+[_])(?<=[_])", path)
     pattern = pattern.groups()
     filename.append(pattern[0])

但是,输出不是我所期望的。这是代码的输出:

filename = [None,
            'normal.jsp_',
            'hbase-env.sh_',
            None,
            None,
            'jar.sha1_',
            '0.xsd_',
            'README.TXT_']

我需要帮助来修复正则表达式。非常感谢。

【问题讨论】:

  • 所以你想要最后一个/_之间的内容?正则表达式是正确的工具吗?
  • [re.search(r'/histogram/([^_/]+)', x).group(1) for x in path_list]
  • 是的,我需要最后一个/ 和第一个_ 之间的内容。
  • 那么你只需要.*/([^_]+)((?&lt;=\/)[a-zA-Z0-9-.]+(?!.+\/)(?=_)) 看起来太复杂了,你可以用什么。

标签: python regex list expression


【解决方案1】:

你可以像这样使用 os.path.basename:

import os

path_list = ['/Users/buggylines/histogram/offline-deployer-list_b7bacc7fdb-0e0e08077c_GERONIMO-2886_635_histogrambuglines_635.diff',
         '/Users/buggylines/histogram/normal.jsp_aa0c2c26dd-90188cc2a4_GERONIMO-4597_1293_histogrambuglines_1293.diff',
         '/Users/buggylines/histogram/hbase-env.sh_aa0c2c26dd-90188cc2a4_GERONIMO-4597_1293_histogrambuglines_1293.diff',
         '/Users/buggylines/histogram/LICENSE-tesh_cd1ec17e43-4ebc5e8021_GERONIMO-5702_1573_histogrambuglines_785.diff',
         '/Users/buggylines/histogram/geronimo_dcce59ae71-8f5c1aa7a1_GERONIMO-5661_1554_histogrambuglines_54.diff',
         '/Users/buggylines/histogram/catalina-6.0.18-G678601.jar.sha1_cd1ec17e43-4ebc5e8021_GERONIMO-5702_1573_histogrambuglines_785.diff',
         '/Users/buggylines/histogram/geronimo-naming-1.0.xsd_544dee5179-40a2ae1d41_GERONIMO-1027_131_histogrambuglines_131.diff',
         '/Users/buggylines/histogram/6.0.18-G678601.README.TXT_cd1ec17e43-4ebc5e8021_GERONIMO-5702_1573_histogrambuglines_785.diff'
        ]

output = [os.path.basename(path).split('_')[0] for path in path_list]    

print(output)

输出:

['offline-deployer-list', 'normal.jsp', 'hbase-env.sh', 'LICENSE-tesh', 'geronimo', 'catalina-6.0.18-G678601.jar.sha1', 'geronimo-naming-1.0.xsd', '6.0.18-G678601.README.TXT']

【讨论】:

  • 它有效。但我需要使用正则表达式来完成我的作业。
【解决方案2】:

这是一个适合我的:

((?<=histogram\/)[a-zA-Z0-9-.]+(?=_))

在这里查看 https://regex101.com/r/VfQIJC/4

更新

一个更通用的匹配最后一个 / 和它之后的第一个 _ 是这样的:

((?<=\/)[a-zA-Z0-9-.]+(?!.+\/)(?=_))

https://regex101.com/r/VfQIJC/5

【讨论】:

  • 抱歉,您的正则表达式运行良好。但是如果路径中包含_,那就不行了。例如。 /Users/analyze_geronimo/histogram/offline-deployer-list_b7bacc7fdb-0e0e08077c_GERONIMO-2886_635_histogrambuglines_635.diff
  • 啊,太好了。它比我的正则表达式更有效且更简单。谢谢
【解决方案3】:
import re
path_list = ['/Users/buggylines/histogram/offline-deployer-list_b7bacc7fdb-0e0e08077c_GERONIMO-2886_635_histogrambuglines_635.diff',
             '/Users/buggylines/histogram/normal.jsp_aa0c2c26dd-90188cc2a4_GERONIMO-4597_1293_histogrambuglines_1293.diff',
             '/Users/buggylines/histogram/hbase-env.sh_aa0c2c26dd-90188cc2a4_GERONIMO-4597_1293_histogrambuglines_1293.diff',
             '/Users/buggylines/histogram/LICENSE-tesh_cd1ec17e43-4ebc5e8021_GERONIMO-5702_1573_histogrambuglines_785.diff',
             '/Users/buggylines/histogram/geronimo_dcce59ae71-8f5c1aa7a1_GERONIMO-5661_1554_histogrambuglines_54.diff',
             '/Users/buggylines/histogram/catalina-6.0.18-G678601.jar.sha1_cd1ec17e43-4ebc5e8021_GERONIMO-5702_1573_histogrambuglines_785.diff',
             '/Users/buggylines/histogram/geronimo-naming-1.0.xsd_544dee5179-40a2ae1d41_GERONIMO-1027_131_histogrambuglines_131.diff',
             '/Users/buggylines/histogram/6.0.18-G678601.README.TXT_cd1ec17e43-4ebc5e8021_GERONIMO-5702_1573_histogrambuglines_785.diff'
            ]

for i in path_list:
    s = re.search(r"\/\w+\/\w+\/\w+\/([^_/]+)", i)
    if s:
        print(s.group(1))

输出:

offline-deployer-list
normal.jsp
hbase-env.sh
LICENSE-tesh
geronimo
catalina-6.0.18-G678601.jar.sha1
geronimo-naming-1.0.xsd
6.0.18-G678601.README.TXT

【讨论】:

    【解决方案4】:

    为什么不使用拆分?

    >>> list = [x.split("/")[-1].split("_")[0] for x in path_list]
    >>> list
    ['offline-deployer-list', 'normal.jsp', 'hbase-env.sh', 'LICENSE-tesh', 'geronimo', 'catalina-6.0.18-G678601.jar.sha1', 'geronimo-naming-1.0.xsd', '6.0.18-G678601.README.TXT']
    

    【讨论】:

    • 对不起,我需要使用正则表达式,因为它是一个作业。
    【解决方案5】:

    这是一个非常pythonic的解决方案。

    import re
    
    path_list = ['/Users/buggylines/histogram/offline-deployer-list_b7bacc7fdb-0e0e08077c_GERONIMO-2886_635_histogrambuglines_635.diff',
             '/Users/buggylines/histogram/normal.jsp_aa0c2c26dd-90188cc2a4_GERONIMO-4597_1293_histogrambuglines_1293.diff',
             '/Users/buggylines/histogram/hbase-env.sh_aa0c2c26dd-90188cc2a4_GERONIMO-4597_1293_histogrambuglines_1293.diff',
             '/Users/buggylines/histogram/LICENSE-tesh_cd1ec17e43-4ebc5e8021_GERONIMO-5702_1573_histogrambuglines_785.diff',
             '/Users/buggylines/histogram/geronimo_dcce59ae71-8f5c1aa7a1_GERONIMO-5661_1554_histogrambuglines_54.diff',
             '/Users/buggylines/histogram/catalina-6.0.18-G678601.jar.sha1_cd1ec17e43-4ebc5e8021_GERONIMO-5702_1573_histogrambuglines_785.diff',
             '/Users/buggylines/histogram/geronimo-naming-1.0.xsd_544dee5179-40a2ae1d41_GERONIMO-1027_131_histogrambuglines_131.diff',
             '/Users/buggylines/histogram/6.0.18-G678601.README.TXT_cd1ec17e43-4ebc5e8021_GERONIMO-5702_1573_histogrambuglines_785.diff'
            ]
    
    
    filename_re = re.compile(r'^\/Users\/buggylines\/histogram\/(?P<filename>[A-Za-z0-9-.]+)_')
    
    filename = []
    for item in path_list:
        filename_match = filename_re.search(item)
        if filename_match:
             filename.append(filename_match.group('filename'))
    
    print(filename)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-07
      • 2020-02-17
      • 2013-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-19
      相关资源
      最近更新 更多