2016-05-11 10 views
1

Ich versuche zu ermitteln, ob eine angegebene Zeichenfolge Zeichen enthält, die genau zweimal wiederholt werden. Im Folgenden ist der reguläre Ausdruck, die ich verwende:Regulärer Ausdruck, der mit jedem exakt doppelt wiederholten Zeichen übereinstimmt

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

Wenn jedoch gegen folgende Saiten getestet, sowohl die Saiten unten passen zum Muster (obwohl ich verwendet habe (\ 1):?!

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

nicht sicher, was in dem obigen Muster falsch ist

+4

Wenn es hilft man darüber nachdenkt ... im letzteren Beispiel die Muster entspricht dem 'eef' Teil der Zeichenkette – donkopotamus

+0

Was ist die erwartete Ausgabe, wenn die Eingabe' acedeefg' ist? –

+0

Danke @donkopotamus. Ich stimme zu, es entspricht dem Eef-Anteil. Ich möchte, dass es nur abcdeefg und nicht abcdeeefg –

Antwort

1

ich vermute, dass ein python regulärer Ausdruck allein nicht Ihre Anforderungen entspricht. um sicherzustellen, dass ein Zeichen genau zweimal wiederholt wird, wird einen negativen Blick hinter Behauptung erfordern, und solche Behauptungen können g nicht enthalten Gruppenreferenzen.

Der einfachste Ansatz besteht darin, stattdessen nach allen Wiederholungen zu suchen und einfach deren Länge zu überprüfen.

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] 

Dann:

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

könnten Sie regex alternativen Betreiber Trick verwenden.

>>> 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,} einstimmt alle wiederholten Zeichen von 3 min max von N Zeichen aufweisen.

  • | OR

  • ([a-z])\2 Einstimmungen genau zwei wiederholten Zeichen aus der Zeichenfolge, da alle restlichen der gleichen kontinuierlichen Zeichen werden von dem ersten Muster übereinstimmt.

oder

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

Wenn Sie wie die anderen answere bekommen Ausgabe wollen dann hier gehen Sie,

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

Das ist nett. Eine Falte ist, dass 'rate ('aaabaa')' '' '' '' '' zurckkehrt, obwohl 'a' genau zweimal wiederholt wird. – donkopotamus

+0

Vielen Dank für die Antworten. Beide Antworten funktionieren –

+0

@donkopotamus hat alle möglichen Optionen hinzugefügt .. –

Verwandte Themen