Python 正则表达式返回空字符串

3 投票
3 回答
1813 浏览
提问于 2025-04-17 17:29

首先,我对正则表达式(regex)还是个新手。不过到目前为止,我对它们非常喜欢。我正在用正则表达式从渲染引擎得到的图像文件名中提取信息。到现在为止,这个正则表达式的效果还不错……

_([a-z]{2,8})_?(\d{1,2})?(\.|_)(\d{3,10})\.([a-z]{2,6})$

如果我在一个文件名上使用split()方法,比如……

image_file_name_ao.0001.exr

我会得到一个很不错的小列表,可以用来处理……

['image_file_name', 'gi', None, '.', '0001', 'exr', '']

我唯一担心的是,它总是会在最后返回一个空字符串。无论我怎么改变或调整正则表达式,最后的列表里总是有一个空字符串。我完全可以选择忽略它继续往下走,但我想问问,是不是我在使用正则表达式时做错了什么,或者有没有什么方法可以避免这个最后的空字符串?谢谢你的时间。

3 个回答

1

你可以使用 filter() 这个函数。

根据你的例子,它的工作方式是这样的:

def f(x):
    return x != '' 

filter
(
    f,
    re.split('_([a-z]{2,8})_?(\d{1,2})?(\.|_)(\d{3,10})\.([a-z]{2,6})$',
    'image_file_name_ao.0001.exr')
)
1

这个问题很有意思。

我稍微修改了一下正则表达式的模式:

import re

reg = re.compile('_([a-z]{2,8})'

                 '_?(\d\d?)?'

                 '([._])'
                 '(\d{3,10})'
                 '\.'
                 '(?=[a-z]{2,6}$)')

for ss in ('image_file_name_ao.0001.exr',
           'image_file_name_45_ao.0001.exr',
           'image_file_name_ao_78.0001.exr',
           'image_file_name_ao78.0001.exr'):
    print '%s\n%r\n' % ( ss, reg.split(ss) )

结果

image_file_name_ao.0001.exr
['image_file_name', 'ao', None, '.', '0001', 'exr']

image_file_name_45_ao.0001.exr
['image_file_name_45', 'ao', None, '.', '0001', 'exr']

image_file_name_ao_78.0001.exr
['image_file_name', 'ao', '78', '.', '0001', 'exr']

image_file_name_ao78.0001.exr
['image_file_name', 'ao', '78', '.', '0001', 'exr']
3

这没什么好奇怪的。split 方法会根据你给的规则把字符串切分开。而你的规则只匹配到行尾的部分(因为它的结尾有个 $),所以在文件名的末尾没有东西可以切分,只剩下一个空的后缀 ('')。

既然你在表达式中已经使用了分组 "(...)",那么你也可以使用 re.match(regex, string)。这样你会得到一个 MatchObject 实例,你可以通过 groups() 方法获取一个包含你分组的元组:

# additional group up front
reg='(\S*)_([a-z]{2,8})_?(\d{1,2})?(\.|_)(\d{3,10})\.([a-z]{2,6})$' 
print re.match(reg, filename).groups() # request tuple of group matches

补充:我真的很抱歉,我没有意识到 你的模式并没有从文件名的第一个字符开始匹配。我在我的回答中进行了扩展。如果你想继续使用 split() 的方法,你也可以修改你最初的模式,让文件名的最后部分不被匹配,这样就可以切分掉了。

撰写回答