2010-11-25 3 views
6

Ich bin auf der Suche nach einer effizienten Möglichkeit, eine Zeichenfolge so zu ändern, dass alle Folgen von mehr als 2 gleichen Zeichen nach den ersten 2 abgeschnitten werden.Python: wie Sequenzen von mehr als 2 gleichen Zeichen in einer Zeichenfolge abgeschnitten werden

Einige Input-> Ausgangs Beispiele sind:

hellooooooooo -> helloo 
woooohhooooo -> woohhoo 

ich zur Zeit über die Charaktere Looping, aber es ist ein bisschen langsam. Hat jemand eine andere Lösung (regexp oder etwas anderes)

EDIT: aktuelle Code:

word_new = "" 
     for i in range(0,len(word)-2):  
      if not word[i] == word[i+1] == word[i+2]: 
       word_new = word_new+word[i] 
     for i in range(len(word)-2,len(word)): 
      word_new = word_new + word[i] 
+0

Könnten Sie Ihren aktuellen Code posten? – Simone

Antwort

8

Edit: nach hilfreichen Kommentaren Anwendung

import re 

def ReplaceThreeOrMore(s): 
    # pattern to look for three or more repetitions of any character, including 
    # newlines. 
    pattern = re.compile(r"(.)\1{2,}", re.DOTALL) 
    return pattern.sub(r"\1\1", s) 

(Original Antwort hier) Versuchen Sie etwas wie dieses:

import re 

# look for a character followed by at least one repetition of itself. 
pattern = re.compile(r"(\w)\1+") 

# a function to perform the substitution we need: 
def repl(matchObj): 
    char = matchObj.group(1) 
    return "%s%s" % (char, char) 

>>> pattern.sub(repl, "Foooooooooootball") 
'Football' 
+0

Sie können dieses Muster '(\ w) \ 1 {2,}' verwenden, um nur die Zeichen in Gruppen von 3 oder mehr zu finden. Du machst auch Trefferpaare. –

+0

Ich denke, du meintest 'pattern_ (repl," Foooooooooootball ")' in der letzten Zeile, aber anders als das, toller Code! – EdoDodo

+0

@Edo - danke für den Fang; korrigiert. @ Alpha-Maus - wahr, aber effektiv ein No-Op. (ersetzt ein Paar mit dem gleichen Paar) – bgporter

0

Ich weiß nicht wirklich Python regexp wissen, aber man könnte diese eine Anpassung:

s/((.)\2)\2+/$1/g; 
1

auch einen regulären Ausdruck verwenden, aber ohne eine Funktion:

import re 

expr = r'(.)\1{3,}' 
replace_by = r'\1\1' 

mystr1 = 'hellooooooo' 
print re.sub(expr, replace_by, mystr1) 

mystr2 = 'woooohhooooo' 
print re.sub(expr, replace_by, mystr2) 
+0

Dies funktioniert nicht bei Sequenzen mit genau drei identischen Zeichen und greift keine Zeilenumbrüche an. –

0

ich meinen Code zu veröffentlichen, es ist nicht Regex, aber seit Sie erwähnt "oder etwas anderes" ...

def removeD(input): 
if len(input) < 3: return input 

output = input[0:2] 
for i in range (2, len(input)): 
    if not input[i] == input[i-1] == input[i-2]: 
     output += input[i] 

return output 

ist nicht als bgporter's (kein Witz, ich mag es wirklich mehr als meins!) Aber - zumindest auf meinem System - time berichten, dass es immer schneller macht.

2

Der folgende Code (im Gegensatz zu anderen Regexp-basierten Antworten) genau das, was Sie sagen, dass Sie wollen: Ersetzen Sie alle Sequenzen von mehr als 2 gleichen Zeichen durch 2 derselben.

>>> import re 
>>> text = 'the numberr offf\n\n\n\ntheeee beast is 666 ...' 
>>> pattern = r'(.)\1{2,}' 
>>> repl = r'\1\1' 
>>> re.sub(pattern, repl, text, flags=re.DOTALL) 
'the numberr off\n\nthee beast is 66 ..' 
>>> 

Sie können nicht wirklich wollen, diese Behandlung ganz oder teilweise anwenden: Ziffern, Interpunktionszeichen, Leerzeichen, Tabulatoren, Zeilenumbrüche etcccc. In diesem Fall müssen Sie die . durch ein restriktiveres Untermuster ersetzen.

Zum Beispiel:

ASCII-Buchstaben: [A-Za-z]

Alle Buchstaben, abhängig von der locale: [^\W\d_] in Verbindung mit der re.LOCALE Flagge

+0

Sie haben Recht, ich muss mehr als nur ASCII-Zeichen ersetzen. Wahrscheinlich Ascii + Interpunktion, aber ich habe mich noch nicht entschieden. Jetzt weiß ich, wie es geht, Danke – Bart

Verwandte Themen