2011-08-06 68 views
3

什麼是限制重複字母下降到1和2,如最好的方法:
appppppppple => APLE和蘋果
bbbbbeeeeeer => BER,啤酒,BBER,bbeer蟒蛇限制重複字母

權現在,我有這樣的:

a = "hellllllllllooooooooooooo" 
    match = re.search('(.)\\1+', a) 

    if match: 
     print 'found' 
     print re.sub('(.)\\1+', '\\1', a) 
     print re.sub('(.)\\1+', '\\1\\1', a) 
    else: 
     print 'not found' 

但它只返回:

helo 
helloo 

^h我可以讓它按照我想要的方式工作嗎?

+0

我不是正則表達式專家,但是對我而言,您需要處理每個重複的信件。現在看來,你只是將它作爲最近的重複信函來處理。也許像'('(。)\\ 1 +)*'? –

+0

我得到無效表達式:'((。)\\ 1 +)*' – Raptrex

+0

S'why我把它作爲一個評論,而不是一個答案:)它主要是爲了舉例說明理論:你需要捕獲每個單獨的重複字母;不只是最後一個。我不知道那個語法。 –

回答

5

不要爲此使用RE。 RE適用於搜索,匹配和轉換,但不適用於生成字符串的

我們可以考慮一個字符串作爲一個向量;每個字母都是一個維度,重複次數是沿着該維度的組件的長度。給定一個矢量V,你想要所有可能的矢量與V相同,這樣如果V的對應分量是1,那麼每個分量的值是1,否則是1或2。基於此,這裏有一個功能可以實現你想要的功能。

def doppelstring(s): 
    letter_groups = ((val, list(group)) for val, group in itertools.groupby(s)) 
    max_vector = ((val, min(len(group), 2)) for val, group in letter_groups) 
    vector_components = ([dim * (l + 1) for l in range(maxlen)] for dim, maxlen in max_vector) 
    return [''.join(letters) for letters in itertools.product(*vector_components)] 

這是一個更緊湊的版本,使用切片。它可能是一個有點不太可讀,但至少保持了78個字符限制之內:

def doppelstring(s): 
    max_vs = (''.join(itertools.islice(g, 2)) for k, g in itertools.groupby(s)) 
    components = ([s[:l + 1] for l in range(len(s))] for s in max_vs) 
    return [''.join(letters) for letters in itertools.product(*components)] 
+2

+1在這種情況下阻止使用正則表達式。該案件不規則,所以正則表達式不適用。 – vstrien

+0

正則表達式可能不是最好的解決方案,但不是因爲問題不規律。正則表達式一直能夠匹配非常規語言,因爲像\ 1這樣的反向引用顯示。 –

2
import re 

def permute(seq): 
    if len(seq) < 2: 
     yield seq 
    else: 
     for tail in permute(seq[2:]): 
      yield seq[:2] + tail 
      yield seq[:2] + seq[1:2] + tail 

text = "hellllllllllooooooooooooo" 
seq = re.split('(.)\\1+', text) 

for result in permute(seq): 
    print ''.join(result) 
+0

我也喜歡+1,但我不確定'permute'是否是最好的詞... – senderle

+0

senderle:true。 Permute就是一個排列組合;因此內存密集(並且在生成時也是計算密集型的)。 – vstrien

0

下面是突然出現在我的腦海裏第一非正則表達式方式

首先製作一個通用squeeze功能:

def squeeze(str, chars='abcdefghijklmnopqrstuvwxyz', min=1): 
    new_str = str 
    for c in chars: 
     new_str = new_str.replace(c*(1+min),c*min) 
    if new_str != str: 
     new_str = squeeze(new_str, min=min) 
    return new_str 

>>> squeeze('aaaabbbbcccc') 
'abc' 
>>> squeeze('aaaabbbbcccc', min=2) 
'aabbcc' 

然後,我們可以寫的小功能,將產生每個「擠壓置換」,可以用來初始化一個set

def squeezutations(str): 
    str = squeeze(str, chars=set(str), min=2) 
    for j,k in ((j,k) for j in range(2,0,-1) for k in range(1,3)): 
     for c in set(str): 
      yield squeeze(squeeze(str, chars=c, min=k), chars=set(str)-set(c), min=j) 

>>> set(squeezutations('appppppppple')) 
set(['apple', 'aple'])