2009-10-01 44 views

回答

3

這將是一個簡潔的方式:

import re 

s = "aa67bc54c9" 
print ''.join(t * int(n) for t, n in re.findall(r"([a-z]+)([0-9]+)", s)) 

該解決方案使用正則表達式匹配「一個或多個字母后跟一個或多個數字」,尋找在所有這些輸入字符串。然後它使用列表理解遍歷每個找到的組,並依次將字母分配給tn。該列表使用字符串*運算符生成字符串,該運算符將字符串重複給定次數(使用int()將數字字符串轉換爲整數)。最後,使用''.join()將所有內容粘貼在一起。

對於正則表達式,[a-z]是由任何單個(小寫)字母組成的字符類。 [a-z]+表示一個或多個小寫字母。同樣,[0-9]+表示一個或多個數字。每個組件周圍的分組括號會「捕捉」其中的字符,並使其可用作爲findall()函數的結果。有兩組圓括號,所以有兩個輸出值,它們在列表理解中被分配到tn

+0

非常感謝你的回答,你可以請exaplin正則表達式([a-z] +)([0-9] +) – Edwards 2009-10-01 03:56:32

+0

如果StackOverflow對我沒有下降,完全會擊敗你。但我會給它一點空間。 – 2009-10-01 03:56:54

+0

爲了理解正則表達式,首先閱讀我的答案。有關Python中正則表達式的完整說明,請參閱以下教程:http://www.amk.ca/python/howto/regex/ – steveha 2009-10-01 06:08:06

3

這是我的Python解決方案。

import re 
pat = re.compile("^(\D+)(\d+)(.*)$") 

def rle_expand(s): 
    lst = [] 
    while True: 
     m = pat.match(s) 
     if m: 
      n = int(m.group(2)) 
      lst.append(m.group(1) * n) 
     else: 
      lst.append(s) 
      break 
     s = m.group(3) 
    return "".join(lst) 

s = "aa03bc05d9whew" 

print rle_expand(s) 
# prints aaaaaabcbcbcbcbcdddddddddwhew 

s = 「aa67bc54c9」 
print rle_expand(s) 
# prints: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcccccccccc 

問題基本上是擴展一個遊程編碼。首先你有某種模式,然後是一些數字,指定重複模式的次數。

首先我們導入re模塊,以訪問Python的正則表達式。

接下來我們編譯一次模式,以便稍後使用它。這種模式會做什麼?

該模式使用圓括號標記匹配字符串中的字母組。有三對parens,所以這將匹配三組。在第一組是一個'^'字符之前,它錨定到字符串的開頭,並且在最後一組之後是一個'$'字符,它錨定在字符串的末尾;在這種情況下,這些並不是絕對必要的。第一組匹配使用特殊序列而不是的任何數字\D; +擴展它以匹配一個或多個非數字實例的運行。第二組類似,使用\d+來匹配一個或多個數字的運行。第三組使用.來匹配任何字符,然後用*擴展它以匹配任意字符的0或更多的運行。 (注意:*+非常相似,它只是*匹配0個或更多的東西,+匹配一個或多個)。

使用標準的Python的成語,我們建立使用列表的字符串。我們從一個空的列表開始(稱爲lst)。只要模式保持匹配的東西,我們將東西附加到這個列表中。當我們完成後,我們使用"".join()將列表一起加入到一個字符串中。

pat.match()返回一個名爲「匹配對象」的對象,或者如果匹配失敗,返回None。如果匹配成功,我們將匹配組2轉換爲整數,並在匹配組1上使用Python字符串重複運算符(「multiply」)進行運行長度擴展。在此之後,我們用匹配組3的結果重新命名s的名稱,從而截斷剛剛處理的字符串部分,並循環。如果匹配失敗,我們只需將所有s附加到列表中並跳出循環。

建立一個列表,然後在列表上使用"".join()是一個標準的Python成語。它可以在任何版本的Python下都有良好的性能。因爲Python字符串是不可變的,所以如果通過重複附加到字符串來建立長動態字符串,性能可能會非常慢;在創建最終字符串時,您會多次複製字符串的早期部分。 Python列表可以簡單地附加到,然後最後的連接操作非常快。 (Python的最新版本已經優化了你反覆附加到一個字符串的情況,並且不再遭受這種情況下的重複複製。)

Greg Hewgill的解決方案只識別從'a'到'z的小寫字母'爲擴展文本;你可以通過把\D而不是[a-z]來解決這個問題。他的解決方案使用明確的範圍,如[0-9],其中我的解決方案使用Python簡寫縮寫(如\d)。他的解決方案只擴展了遊程編碼序列;如果有一個尾部序列沒有整數,那麼我的這個序列不變,而他默默地忽略它。但是,必須說他的解決方案非常優雅,我希望我能想到它。 :-)

+0

Stevha非常感謝您的優雅解釋以及擴展的正則表達式。希望stackoverflow允許我選擇更多,然後誠實地回答這個使用列表來獲得我想要的是第一個想到的解決方案。 – Edwards 2009-10-01 07:38:55