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

NSc*_*ing 20 python string

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

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

import re    
pattern = "***abc**de*fg******h"
pattern.replace("*"\*, "*")
Run Code Online (Sandbox Code Playgroud)

\*应该在哪里替换"*"字符的所有实例.但我得到了:SyntaxError:行继续符后的意外字符.

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

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

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

任何帮助,将不胜感激.

Joh*_*hin 24

做这种事的天真的方法re

re.sub('\*+', '*', text)
Run Code Online (Sandbox Code Playgroud)

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

re.sub('\*\*+', '*', text)
Run Code Online (Sandbox Code Playgroud)

这非常值得做:

\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
Run Code Online (Sandbox Code Playgroud)

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

  • @Medorator不确定易读性......一旦JAvg理解`\ X`,跳转到'\ X\X`对我来说似乎很小.也许`\ X {2,}`会更好?我希望JAvg不会盲目做任何事情.如果输出要求更改为"查找所有重复的星号",您可能会认为正则表达式已从1+更改为2+. (3认同)

gho*_*g74 7

如何非正则表达方式

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


Jos*_*shD 5

我建议使用re模块子功能:

import re

result = re.sub("\*+", "*", "***abc**de*fg******h")
Run Code Online (Sandbox Code Playgroud)

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

  • @NSchrading:在““ \\ * +”`中,我转义了*字符,因为它是一个特殊的re符号。因此,我匹配一个文字*字符,而+表示一个或多个。 (2认同)

tzo*_*zot 5

你写了:

pattern.replace("*"\*, "*")
Run Code Online (Sandbox Code Playgroud)

你的意思是:

pattern.replace("\**", "*")
#                ^^^^
Run Code Online (Sandbox Code Playgroud)

你真正的意思是:

pattern_after_substitution= re.sub(r"\*+", "*", pattern)
Run Code Online (Sandbox Code Playgroud)

这就是你想要的。


Hug*_*ugo 5

我对当前答案中的所有方法进行了计时(使用 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
Run Code Online (Sandbox Code Playgroud)

输入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 usec
  • b) 100000 个循环,5 个循环中最好的:每个循环 3.17 usec
  • c) 500000 个循环,5 个循环中最好的:每个循环 508 纳秒
  • d) 10000 个循环,5 个循环中最好的:每个循环 25.4 usec
  • e) 5000 个循环,5 个循环中最好的:每个循环 44.7 usec
  • 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 usec
  • b) 50000 个循环,5 个循环中最好的:每个循环 5.21 usec
  • c) 20000 个循环,5 个循环中最好的:每个循环 13.4 usec
  • d) 5000 个循环,5 个循环中最好的:每个循环 47.4 usec
  • e) 2000 个循环,5 个循环中最好的:每个循环 103 usec
  • f) 20000 个循环,5 个循环中最好的:每个循环 13.1 usec

b() 总体上最好,c() 如果没有匹配则最好

方法:

#!/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
Run Code Online (Sandbox Code Playgroud)