2012-09-24 43 views
1

我刚刚学习和使用正则表达式的动力性格实例 我从os.walk()返回的文件的元组列表,像这样:正则表达式替换基于模式或分隔符

files = ('s8_00.tif', 's9_00.tif', 's10_000.tif', 's11_00.tif') 

我想得到它看起来像这样:

files = ('s8_##.tif', 's9_##.tif', 's10_###.tif', 's11_##.tif') 

我试图使用这个。

pad2 = re.compile(r'_00?') 

for root, dirs, files in seqDirs: 
    pad = files[0] 
    p = pad2.sub("#", pad) 
    print p 

这将返回:

p = ('s8#.tif', 's9#.tif', 's10#0.tif', 's11#.tif') 

所以我改变了表达绕到:

pad2 = re.compile('(_)0+') 

给我:

p = ('s8#.tif', 's9#.tif', 's10#.tif', 's11#.tif') 

是我p = pad2.sub功能的问题?或者是我的编译表达式中存在问题?或者这是"_"在表达,它是在搞砸了吗?

我甚至试过在pad2.sub函数中传递一些表达式来测试它,当然这并没有真正起作用。我知道我在这里错过了一些小东西,而且我有点卡住了。

随着逻辑的解释,任何和所有的帮助将不胜感激。

回答

5

我们打算使用替换函数,而不是字符串。

def replacer(data): 
    return re.sub(r'(?<=_)(0+)', lambda m: m.group(0).replace('0', '#'), data) 

files = ('s8_000.tif', 's9_00.tif', 's10_000.tif', 's11_00.tif') 
map(replacer, files) 
print(files) 

?<=正向后断言。您可以在Regular Expression Syntax的文档中找到解释。

0+捕获所有以下零

拉姆达函数替换每0#

+0

真棒,非常感谢,这绝对是一个很酷的功能。我可以看到这个很棒的扩展性。 –

2

如果你想这样做,其中任意数量的可能是在那里,让你的正则表达式是

pattern = re.compile("_(\d+)")

pattern.sub("_"+len("\g<1>")*"#", filename)

做替换在您可以访问任何正则表达式与第一个值“\ g < 1>”相关的元素被捕获的是什么,以及下一组元素是否为“\ g < 2>”等。 “\ d +”将获得表达式中的任何数字字符。如果你非常特别的只是想找零,你可以用“_(0+)”代替它。

+0

那么如果他不知道他想要替换多少数字,他会怎么做? –

+0

@BostonJohn我知道我可以非常直接地用这种方式替换字符。但这些文件有时会有3个或更多的零,那么这将无法满足我的需求。 –

0

你最好找到匹配,计算它们的长度,然后用它们的数目替换它们# s。

+0

这给了我 “引发错误,V#无效表达 sre_constants.error:没有重复” 我想我会尝试一些与你的第二个建议,虽然。 –

+0

@ J.A.M是的,我猜你不能在python中使用可变长度lookbehinds。这是愚蠢的。 –

+0

@ J.A.M看看最热门的答案 - 它的确如我所说的/会做的 –