python限制重复字母

时间:2011-08-06 17:09:07

标签: python regex string

将重复字母限制为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

如何让它以我想要的方式运作?

3 个答案:

答案 0 :(得分: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-char限制范围内:

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)]

答案 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)

答案 2 :(得分: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'])