2010-11-25 7 views
6

2文字以上のすべての文字列が最初の2文字の後に途切れないように、効率的な方法を探しています。Python:文字列中の2つ以上の等しい文字のシーケンスを切り取る方法

いくつかの入力 - >出力例は以下のとおりです。

hellooooooooo -> helloo 
woooohhooooo -> woohhoo 

私は現在の文字をループしていますが、それは少し遅いです。現在のコード:

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

あなたの現在のコードを投稿してもらえますか? – Simone

答えて

8

編集:

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) 

有益なコメントを適用した後(ここでは元の応答誰もが別のソリューション(正規表現または他の何か)

EDITを持っています) このようなものを試す:

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

このパターン '(\ w)\ 1 {2、}'を使用すると、3つ以上のグループに属する文字だけを照合することができます。あなたはヒットペアもパターン化します。 –

+0

最後の行で 'pattern.sub(repl、" Foooooooooootball ")'を意味すると思いますが、それ以外の素晴らしいコード! – EdoDodo

+0

@エド - キャッチのおかげで;修正されました。 @アルファ - マウス - 真実ですが、事実上ノーオペレーションです。 (ペアを同じペアに置き換える) – bgporter

0

私は本当にPythonの正規表現を知らないが、あなたは、このいずれかを適応させることができます:

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

はまた、正規表現を使用しますが、機能なし:

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

これはまったく同じ3文字のシーケンスでは機能せず、改行を攻撃しません。 –

0

私は私のコードを投稿し、それは正規表現ではありませんが、あなたが「何か他のもの」と言いましたので...

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 

はbgporterのものではありません(冗談はありませんが、私はそれ以上のものが大好きです)。 - 少なくとも私のシステムでは - timeは常に高速に実行されると報告します。

2

次のコード(他のregexpベースの回答とは異なります)は、あなたが言うことを正確に行います。2つ以上の等しい文字のすべてのシーケンスを2つ置き換えます。数字、句読点、スペース、タブ、改行etcccc:

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

は、あなたは本当に一部またはすべてにこの治療法を適用したくない場合があります。その場合は、.をより限定的なサブパターンに置き換える必要があります。例えば

ASCII文字:[A-Za-z]

任意の文字、ロケールによって:re.LOCALEフラグと一緒に[^\W\d_]

+0

あなたは正しいです、私はASCII文字以外のものを置き換える必要があります。おそらくascii +句読点ですが、私はまだ決めていません。今私はそれを行う方法を知っています、ありがとう – Bart

関連する問題