Python: как обрезать последовательности из более чем 2 одинаковых символов в строке - PullRequest
6 голосов
/ 25 ноября 2010

Я ищу эффективный способ сделать случайную строку такой, чтобы все последовательности из более чем 2 одинаковых символов обрезались после первых 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]

Ответы [ 5 ]

8 голосов
/ 25 ноября 2010

Редактировать: после применения полезных комментариев

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)

(оригинальный ответ здесь) Попробуйте что-то вроде этого:

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'
2 голосов
/ 25 ноября 2010

Следующий код (в отличие от других ответов на основе регулярных выражений) делает именно то, что вы говорите, что вы хотите: заменить все последовательности более 2 одинаковых символов на 2 одинаковых.

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

Любые буквы в зависимости от локали: [^\W\d_] в сочетании с флагом re.LOCALE

1 голос
/ 25 ноября 2010

Также используется регулярное выражение, но без функции:

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 голосов
/ 25 ноября 2010

Я публикую свой код, это не регулярное выражение , но, поскольку вы упомянули "или что-то еще" ...

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 сообщает, что он всегда работает быстрее.

0 голосов
/ 25 ноября 2010

Я действительно не знаю регулярное выражение Python, но вы могли бы адаптировать это:

s/((.)\2)\2+/$1/g;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...