2012-09-24 85 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看看最熱門的答案 - 它的確如我所說的/會做的 –