2016-05-11 26 views
1

我想識別一個提供的字符串是否有重複兩次的字符。以下是正則表達式,我使用:正則表達式匹配任何重複了兩次的字符

([a-z])\1(?!\1) 

然而,當對下列字符串進行測試,這兩個字符串如下匹配模式(雖然我已經使用(\ 1):?!

>>> re.findall(r'.*([a-z])\1(?!\1)', 'abcdeefg') 
['e'] 
>>> re.findall(r'.*([a-z])\1(?!\1)', 'abcdeeefg') 
['e'] 

不知道什麼是錯在上面的圖案

+4

如果它可以幫助你想想......在後者的例子中模式匹配字符串的'eef'部分 – donkopotamus

+0

如果輸入是'acedeefg',預期的輸出是什麼? –

+0

謝謝@donkopotamus。我同意,這是匹配eef部分。我希望它只匹配abcdeefg,而不匹配 –

回答

1

我懷疑,獨自一個python正則表達式將不能滿足您的需求。爲了確保字符僅重複兩次將需要背後斷言否定的樣子,而這樣的斷言不能包含g分組參考。

最簡單的方法是改爲查找所有重複並簡單檢查它們的長度。

def double_repeats(txt): 
    import itertools 

    # find possible repeats 
    candidates = set(re.findall(r'([a-z])\1', txt)) 

    # now find the actual repeated blocks 
    repeats = itertools.chain(*[re.findall(r"({0}{0}+)".format(c), txt) for c in candidates]) 

    # return just the blocks of length 2 
    return [x for x in repeats if len(x) == 2] 

然後:

>>> double_repeats("abbbcbbdddeffgggg") 
['ff', 'bb'] 
0

你可以使用正則表達式替換的操作技巧。

>>> def guess(s): 
    out = re.findall(r'([a-z])\1{2,}|([a-z])\2', s) 
    if out and out[0][1]: 
     return True 
    return False 

>>> k = ['abcdeefg', 'abcdeeefg'] 
>>> [guess(i) for i in k] 
[True, False] 
>>> 
  • ([a-z])\1{2,}具有3最大n個字符的所有分鐘重複字符相匹配。

  • | OR

  • ([a-z])\2匹配恰好從剩餘的字符串兩個重複的字符,因爲所有的相同的連續字符由第一圖案匹配。

>>> def guess(s): 
    out = re.findall(r'([a-z])\1{2,}|([a-z])\2', s) 
    if out and out[0][1]: 
     return out[0][1] 
    return False 
>>> k = '23413e4abcee' 
>>> k.count(guess(k)) == 2 
False 
>>> k = '234134abcee' 
>>> k.count(guess(k)) == 2 
True 
>>> 

如果你想獲得像其他的answere輸出,那麼在這裏你走,

>>> def guess(s): 
    out = re.findall(r'([a-z])\1{2,}|([a-z])\2', s) 
    if out: 
     return [y+y for x,y in out if y] 
    return [] 

>>> guess("abbbcbbdddeffgggg") 
['bb', 'ff'] 
>>> 
+0

這很好。一個問題是,儘管'a'重複了兩次,猜測('aaabaa')'現在會返回'False'。 – donkopotamus

+0

感謝所有的答案。兩個答案都在工作 –

+0

@donkopotamus添加了所有可能的選項.. –

相關問題