2011-08-06 69 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'])