如何使用re在Python中的另一个列表中的一个列表中搜索项目

时间:2009-12-09 06:38:55

标签: python regex

我正在读取一个字符串列表,每个字符串都与一个文件名相关。但是,每个字符串都是减去扩展名。我想出了以下代码:

import re
item_list = ['item1', 'item2']
search_list = ['item1.exe', 'item2.pdf']
matches = []
for item in item_list:
    # Match item in search_list using re - I assume this is the best way to do this
    regex = re.compile("^"+item+"\.")
    for file in search_list:
        if regex.match(file):
            matches.append((item, file))

至于重复的匹配,我并不十分担心两个文件被命名为'foo.bar'和'foo.foo.bar'。话虽这么说,还有更好的方法吗?

谢谢。

7 个答案:

答案 0 :(得分:2)

您可以将所有项目组合成一个像这样的效率更高效的正则表达式

import re
item_list = ['item1', 'item2']
regex = re.compile("^("+"|".join(item_list)+")\.")
search_list = ['item1.exe', 'item2.pdf']
matches = []
for file in search_list:
    match = regex.match(file)
    if match:
        matches.append((match.group(1), file))

更好的解决方案可能是使用os.path函数解析文件名,但要解析出基本名称并在集合中查找它们。

答案 1 :(得分:2)

使用splitext获取不带扩展名的文件名:

import os.path

for item in item_list:
    for filename in search_list:
        if item == os.path.splitext(filename)[0]:
            matches.append((item, file))

这更正确,但通过阅读代码也更容易理解你的意图。或者,如果你想允许foo匹配foo.bar.txt,那么请改用filename.startswith(item +'。')。

答案 2 :(得分:1)

您不需要使用正则表达式,因为您正在进行精确的字符串匹配(没有通配符,组等) - 您可以使用 str.startswith(..)。这相当于您的代码:

for item in item_list:
    match = item + "."
    for file in search_list:
        if file.startswith(match)
            matches.append((item, file))

然而尼克克雷格 - 伍德关于将所有比赛编译成单个正则表达式的建议可能会更有效率 - 我建议你在速度是一个问题的基础上进行基准测试。

答案 3 :(得分:1)

除非你真的需要,否则请避免使用re。对于简单的字符串匹配,您根本不需要它。

Mark Byers的回答重复了将matches保留在item_list订单中的原始行为。如果你不需要,你可以更简单/更快地完成它:

for file in search_list:
    item= os.path.splitext(file)[0]
    if item in item_list:
        matches.append((item, file))

如果您不需要保持(item)匹配(因为它仍然是文件名中的冗余),您就有了一个单行:

matches= [file for file in search_list if os.path.splitext(file)[0] in item_list]

答案 4 :(得分:0)

这是另一种方法,它可能比Alex的原始代码更快:

item_list = ['item1', 'item2']
search_list = ['item1.exe', 'item2.pdf']
matches = []
for item in item_list:
    for filename in search_list:
        if filename.partition(".")[0] == item:
            matches.append((item,filename))

答案 5 :(得分:0)

我认为你应该使用.rsplit(".",1)来实现这个目的,正则表达式是不是有点过分了?

>>> item_list = ['item1', 'item2','item3']
>>> search_list = ['item1.exe', 'item2.pdf','item9999.txt']
>>>
>>> [(x.rsplit(".",1)[0],x) for x in search_list if x.rsplit(".",1)[0] in item_list]
[('item1', 'item1.exe'), ('item2', 'item2.pdf')]

或for for循环

matches=[]
for x in search_list:
    y=x.rsplit(".",1)[0]
    if y in item_list:
        matches.append((y,x))

答案 6 :(得分:0)

>>> for file in search_list:
...  tomatch=file.split(".")[0]
...  if tomatch in item_list:
...     found=item_list.index(tomatch)
...     matches.append( ( file, item_list[found] ) )
...
>>> print matches
[('item1.exe', 'item1'), ('item2.pdf', 'item2')]
>>>

不需要正则表达式。