如何在python中使用该字符的单个实例替换重复的字符实例

时间:2010-10-07 03:56:54

标签: python string

我想用单个"*"实例替换字符串中"*"个字符的重复实例。例如,如果字符串是"***abc**de*fg******h",我希望它转换为"*abc*de*fg*h"

我对python(以及一般的编程)很新,并尝试使用正则表达式和string.replace(),如:

import re    
pattern = "***abc**de*fg******h"
pattern.replace("*"\*, "*")

其中\*应该替换“*”字符的所有实例。但我得到了:SyntaxError:行继续符后的意外字符。

我也尝试用for循环操作它:

def convertString(pattern):
for i in range(len(pattern)-1):
    if(pattern[i] == pattern[i+1]):
        pattern2 = pattern[i]
return pattern2

但这有错误,它只打印“*”,因为pattern2 = pattern [i]不断重新定义了pattern2是什么......

任何帮助都将不胜感激。

11 个答案:

答案 0 :(得分:20)

使用re执行此类操作的天真方式是

re.sub('\*+', '*', text)

用一个星号替换1个或多个星号的运行。对于只有一个星号的运行,为了保持静止,运行非常困难。更好的方法是用一个星号代替两个或更多星号的运行:

re.sub('\*\*+', '*', text)

这非常值得做:

\python27\python -mtimeit -s"t='a*'*100;import re" "re.sub('\*+', '*', t)"
10000 loops, best of 3: 73.2 usec per loop

\python27\python -mtimeit -s"t='a*'*100;import re" "re.sub('\*\*+', '*', t)"
100000 loops, best of 3: 8.9 usec per loop

请注意,如果找不到匹配项,re.sub将返回对输入字符串的引用,从而减少计算机上的磨损,而不是全新的字符串。

答案 1 :(得分:6)

非正则方式怎么样

def squeeze(char,s):
    while char*2 in s:
        s=s.replace(char*2,char)
    return s
print squeeze("*" , "AB***abc**def**AA***k")

答案 2 :(得分:4)

我建议使用re module子功能:

import re

result = re.sub("\*+", "*", "***abc**de*fg******h")

我强烈建议您阅读有关RE和良好做法的文章。如果你不熟悉它们,它们可能会很棘手。在实践中,使用原始字符串是个好主意。

答案 3 :(得分:2)

您写道:

pattern.replace("*"\*, "*")

你的意思是:

pattern.replace("\**", "*")
#                ^^^^

你的意思是:

pattern_after_substitution= re.sub(r"\*+", "*", pattern)

做你想做的事。

答案 4 :(得分:1)

明智的正则表达式我会像JoshD建议的那样做。但这里有一个改进。

使用 -

regex  = re.compile('\*+')
result = re.sub(regex, "*", string)

这实际上会缓存你的正则表达式。因此,在循环中随后使用它将使您的正则表达式操作快速。

答案 5 :(得分:0)

re.sub('\*+', '*', pattern)

那样做。

答案 6 :(得分:0)

没有正则表达式,您可以通过检查'*'来使用一般重复元素删除:

source = "***abc**dee*fg******h"
target = ''.join(c for c,n in zip(source, source[1:]+' ') if  c+n != '**')
print target

答案 7 :(得分:0)

让我们假设为了这个例子,你的角色是一个空间。

你也可以这样做:

while True:
    if "  " in pattern: # if two spaces are in the variable pattern
        pattern = pattern.replace("  ", " ") # replace two spaces with one
    else: # otherwise
        break # break from the infinite while loop

这:

File Type                       : Win32 EXE
File Type Extension             : exe
MIME Type                       : application/octet-stream
Machine Type                    : Intel 386 or later, and compatibles
Time Stamp                      : 2017:04:24 09:55:04-04:00

变为:

File Type : Win32 EXE
File Type Extension : exe
MIME Type : application/octet-stream
Machine Type : Intel 386 or later, and compatibles
Time Stamp : 2017:04:24 09:55:04-04:00

我发现这比使用re模块更容易一些,有时会让人觉得有点烦恼(我认为)。

希望这很有用。

答案 8 :(得分:0)

这适用于任意数量的连续星号,但您可能需要将波形符替换为您知道在整个字符串中唯一的其他字符串。

    string = "begin*************end"

    string.replace("**", "~*").replace("*~", "").replace("~*", "*").replace("**", "*")

我认为正则表达式的方法通常比计算上更昂贵。

答案 9 :(得分:0)

我为当前答案中的所有方法计时(使用Python 3.7.2,macOS High Sierra)。

b()是最好的,c()是没有比赛的最好。

def b(text):
    re.sub(r"\*\*+", "*", text)

# aka squeeze()
def c(text):
    while "*" * 2 in text:
        text = text.replace("*" * 2, "*")
    return text

输入1,不重复: 'a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*'

  • a)10000次循环,最好是5次:每个循环24.5微秒
  • b)100000次循环,最好是5次:每个循环3.17微秒
  • c)500000次循环,最好是5次:每个循环508纳秒
  • d)10000个循环,最好是5个循环:每个循环25.4 usc
  • e)5000个循环,最好是5个循环:每个循环44.7 usc
  • f) 500000个循环,最好是5个循环:每个循环522纳秒

输入2,重复: 'a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*****************************************************************************************************a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*'

  • a)5000个循环,最好是5个循环:每个循环46.2 usc
  • b) 50000次循环,最好5次:每个循环5.21微秒
  • c)20000个循环,最好是5个循环:每个循环13.4个usec
  • d)5000个循环,最好是5个循环:每个循环47.4 usc
  • e)2000次循环,最好是5次:每个循环103个usec
  • f)20000次循环,最好是5次:每个循环13.1个usec

b() is best overall, c() best if no matches

方法:

#!/usr/bin/env python
# encoding: utf-8
"""
See which function variants are fastest. Run like:
python -mtimeit -s"import time_functions;t='a*'*100" "time_functions.a(t)"
python -mtimeit -s"import time_functions;t='a*'*100" "time_functions.b(t)"
etc.
"""
import re


def a(text):
    return re.sub(r"\*+", "*", text)


def b(text):
    re.sub(r"\*\*+", "*", text)


# aka squeeze()
def c(text):
    while "*" * 2 in text:
        text = text.replace("*" * 2, "*")
    return text


regex = re.compile(r"\*+")


# like a() but with (premature) optimisation
def d(text):
    return re.sub(regex, "*", text)


def e(text):
    return "".join(c for c, n in zip(text, text[1:] + " ") if c + n != "**")


def f(text):
    while True:
        if "**" in text:  # if two stars are in the variable pattern
            text = text.replace("**", "*")  # replace two stars with one
        else:  # otherwise
            break  # break from the infinite while loop
    return text

答案 10 :(得分:-2)

text =“ aaaaaaaaaabbbbbbbbbbbbcccccccddddddaaaaaaaa”

result =“”

对于文本字符:

if len(result) > 0 and result[-1] == char:
    continue
else:
    result += char

打印(结果)#abcda