使用 Python 从字符串中删除特定字符

2024-11-27 10:42:00
admin
原创
16
摘要:问题描述:我正在尝试使用 Python 从字符串中删除特定字符。这是我现在正在使用的代码。不幸的是,它似乎对字符串没有任何作用。for char in line: if char in " ?.!/;:": line.replace(char,'') 我该如何正确地...

问题描述:

我正在尝试使用 Python 从字符串中删除特定字符。这是我现在正在使用的代码。不幸的是,它似乎对字符串没有任何作用。

for char in line:
    if char in " ?.!/;:":
        line.replace(char,'')

我该如何正确地做到这一点?


有关此方法存在什么问题的具体调试问题,请参阅为什么调用字符串方法(例如 .replace 或 .strip)不会修改(变异)字符串? 。这里的答案主要关注如何解决问题。


解决方案 1:

Python 中的字符串是不可变的(无法更改)。因此,的效果line.replace(...)只是创建一个新字符串,而不是更改旧字符串。您需要将其重新绑定(分配)为,line以便让该变量采用新值,并删除那些字符。

此外,你这样做的方式相对来说会比较慢。对于经验丰富的 Python 程序员来说,这也可能有点令人困惑,他们看到双重嵌套结构时会认为其中有更复杂的事情。

从 Python 2.6 和更新的 Python 2.x 版本开始 ,你可以改用str.translate, (请参阅下面的Python 3 答案*):

line = line.translate(None, '!@#$')

或使用正则表达式替换re.sub

import re
line = re.sub('[!@#$]', '', line)

括号内的字符构成一个字符类。 中line属于该类的任何字符都将被替换为第二个参数sub:一个空字符串。

Python 3 答案

在 Python 3 中,字符串是 Unicode。您必须进行稍微不同的翻译。kevpie 在其中一个答案的评论中提到了这一点,并且在的文档str.translate中也提到了这一点。

调用 Unicode 字符串的方法时translate,您不能传递上面使用的第二个参数。您也不能将其None作为第一个参数传递。相反,您传递一个转换表(通常是字典)作为唯一参数。该表将字符的序数值(即调用它们的结果ord)映射到应替换它们的字符的序数值,或者(对我们有用)None指示应删除它们。

因此,要使用 Unicode 字符串执行上述操作,你可以调用类似

translation_table = dict.fromkeys(map(ord, '!@#$'), None)
unicode_line = unicode_line.translate(translation_table)

这里dict.fromkeysmap用于简洁地生成一个包含

{ord('!'): None, ord('@'): None, ...}

甚至更简单,正如另一个答案所说,创建翻译表:

unicode_line = unicode_line.translate({ord(c): None for c in '!@#$'})

或者,正如Joseph Lee所提出的那样,使用以下命令创建相同的翻译表str.maketrans

unicode_line = unicode_line.translate(str.maketrans('', '', '!@#$'))

  • 为了与早期版本的 Python 兼容,您可以创建一个“空”转换表来代替None

import string
line = line.translate(string.maketrans('', ''), '!@#$')

这里string.maketrans用于创建一个转换表,它只是一个包含序数值为 0 到 255 的字符的字符串。

解决方案 2:

我是不是错过了重点,还是只是以下几点:

string = "ab1cd1ef"
string = string.replace("1", "") 

print(string)
# result: "abcdef"

将其放入循环中:

a = "a!b@c#d$"
b = "!@#$"
for char in b:
    a = a.replace(char, "")

print(a)
# result: "abcd"

解决方案 3:

>>> line = "abc#@!?efg12;:?"
>>> ''.join( c for c in line if  c not in '?:!/;' )
'abc#@efg12'

解决方案 4:

使用re.sub正则表达式

从 Python 3.5 开始,re.sub可以使用正则表达式进行替换:

import re
re.sub(' |?|.|!|/|;|:', '', line)

例子

import re
line = 'Q: Do I write ;/.??? No!!!'
re.sub(' |?|.|!|/|;|:', '', line)

'QDoIwriteNo'

解释

在正则表达式(regex)中,|是逻辑或,并`转义可能为实际正则表达式命令的空格和特殊字符。而sub代表**替换,**在本例中为空字符串''`。

解决方案 5:

提问者几乎已经知道了。就像 Python 中的大多数东西一样,答案比你想象的要简单。

>>> line = "H E?.LL!/;O:: "  
>>> for char in ' ?.!/;:':  
...  line = line.replace(char,'')  
...
>>> print line
HELLO

您不必执行嵌套的 if/for 循环,但您确实需要单独检查每个字符。

解决方案 6:

对于仅允许字符串中某些字符的反向要求,可以使用带有集合补码运算符的正则表达式[^ABCabc]。例如,要删除除 ascii 字母、数字和连字符之外的所有内容:

>>> import string
>>> import re
>>>
>>> phrase = '  There were "nine" (9) chick-peas in my pocket!!!      '
>>> allow = string.letters + string.digits + '-'
>>> re.sub('[^%s]' % allow, '', phrase)

'Therewerenine9chick-peasinmypocket'

来自python正则表达式文档:

不在范围内的字符可以通过对集合进行补码来匹配。如果集合的第一个字符是'^',则所有不在集合中的字符都会被匹配。例如,[^5]将匹配除“5”之外的任何字符,并将[^^]匹配除 之外的任何字符
'^'^如果它不是集合中的第一个字符,则没有特殊含义。

解决方案 7:

line = line.translate(None, " ?.!/;:")

解决方案 8:

>>> s = 'a1b2c3'
>>> ''.join(c for c in s if c not in '123')
'abc'

解决方案 9:

在 Python 中字符串是不可变的。该replace方法在替换后返回一个新字符串。尝试:

for char in line:
    if char in " ?.!/;:":
        line = line.replace(char,'')

line这与您的原始代码相同,但在循环内部添加了赋值。

请注意,字符串replace()方法会替换字符串中出现的所有replace()字符,因此,您可以通过对要删除的每个字符使用该方法,而不是循环遍历字符串中的每个字符,从而获得更好的效果。

解决方案 10:

尝试一下这个:

def rm_char(original_str, need2rm):
    ''' Remove charecters in "need2rm" from "original_str" '''
    return original_str.translate(str.maketrans('','',need2rm))

此方法在 Python 3 中有效

解决方案 11:

令我惊讶的是,没有人推荐使用内置过滤功能。

    import operator
    import string # only for the example you could use a custom string

    s = "1212edjaq"

假设我们想过滤掉所有非数字的内容。使用内置的 filter 方法“...相当于生成器表达式 (item for item in iterable if function(item))”[ Python 3 内置函数:Filter ]

    sList = list(s)
    intsList = list(string.digits)
    obj = filter(lambda x: operator.contains(intsList, x), sList)))

在 Python 3 中,这将返回

    >>  <filter object @ hex>

要获得打印的字符串,

    nums = "".join(list(obj))
    print(nums)
    >> "1212"

我不确定过滤器在效率方面的排名如何,但在进行列表理解等时知道如何使用是件好事。

更新

从逻辑上讲,既然过滤器有效,那么你也可以使用列表推导,而且据我所知,它应该更有效,因为 lambda 是编程函数世界中的华尔街对冲基金经理。另一个优点是它是一行代码,不需要任何导入。例如,使用上面定义的相同字符串“s”,

      num = "".join([i for i in s if i.isdigit()])

就是这样。返回的是原始字符串中所有数字字符的字符串。

如果您有一个可接受/不可接受字符的特定列表,您只需要调整列表理解的“if”部分。

      target_chars = "".join([i for i in s if i in some_list]) 

或者,

      target_chars = "".join([i for i in s if i not in some_list])

解决方案 12:

使用filter,你只需要一行

line = filter(lambda char: char not in " ?.!/;:", line)

这将字符串视为可迭代对象并检查每个字符是否lambda返回True

>>> help(filter)
Help on built-in function filter in module __builtin__:

filter(...)
    filter(function or None, sequence) -> list, tuple, or string

    Return those items of sequence for which function(item) is true.  If
    function is None, return the items that are true.  If sequence is a tuple
    or string, return the same type, else return a list.

解决方案 13:

以下是完成此任务的一些可能方法:

def attempt1(string):
    return "".join([v for v in string if v not in ("a", "e", "i", "o", "u")])


def attempt2(string):
    for v in ("a", "e", "i", "o", "u"):
        string = string.replace(v, "")
    return string


def attempt3(string):
    import re
    for v in ("a", "e", "i", "o", "u"):
        string = re.sub(v, "", string)
    return string


def attempt4(string):
    return string.replace("a", "").replace("e", "").replace("i", "").replace("o", "").replace("u", "")


for attempt in [attempt1, attempt2, attempt3, attempt4]:
    print(attempt("murcielago"))

附言:示例中使用元音代替“ ?.!/;:”... 是的,“murcielago” 是西班牙语中表示蝙蝠的意思... 很有趣的词,因为它包含了所有的元音 :)

PS2:如果您对性能感兴趣,您可以使用以下简单的代码来衡量这些尝试:

import timeit


K = 1000000
for i in range(1,5):
    t = timeit.Timer(
        f"attempt{i}('murcielago')",
        setup=f"from __main__ import attempt{i}"
    ).repeat(1, K)
    print(f"attempt{i}",min(t))

在我的盒子里你会得到:

attempt1 2.2334518376057244
attempt2 1.8806643818474513
attempt3 7.214925774955572
attempt4 1.7271184513757465

因此,对于这个特定的输入,似乎 attempt4 是最快的。

解决方案 14:

这是我的 Python 2/3 兼容版本。由于翻译 API 已发生改变。

def remove(str_, chars):
    """Removes each char in `chars` from `str_`.

    Args:
        str_: String to remove characters from
        chars: String of to-be removed characters

    Returns:
        A copy of str_ with `chars` removed

    Example:
            remove("What?!?: darn;", " ?.!:;") => 'Whatdarn'
    """
    try:
        # Python2.x
        return str_.translate(None, chars)
    except TypeError:
        # Python 3.x
        table = {ord(char): None for char in chars}
        return str_.translate(table)

解决方案 15:

#!/usr/bin/python
import re

strs = "how^ much for{} the maple syrup? $20.99? That's[] ricidulous!!!"
print strs
nstr = re.sub(r'[?|$|.|!|a|b]',r' ',strs)#i have taken special character to remove but any #character can be added here
print nstr
nestr = re.sub(r'[^a-zA-Z0-9 ]',r'',nstr)#for removing special character
print nestr

解决方案 16:

您还可以使用函数,通过列表替换不同类型的正则表达式或其他模式。这样,您可以混合正则表达式、字符类和非常基本的文本模式。当您需要替换大量元素(如 HTML 元素)时,它非常有用。

*NB:适用于 Python 3.x

import re  # Regular expression library


def string_cleanup(x, notwanted):
    for item in notwanted:
        x = re.sub(item, '', x)
    return x

line = "<title>My example: <strong>A text %very% $clean!!</strong></title>"
print("Uncleaned: ", line)

# Get rid of html elements
html_elements = ["<title>", "</title>", "<strong>", "</strong>"]
line = string_cleanup(line, html_elements)
print("1st clean: ", line)

# Get rid of special characters
special_chars = ["[!@#$]", "%"]
line = string_cleanup(line, special_chars)
print("2nd clean: ", line)

在函数 string_cleanup 中,它将字符串 x 和列表 notwanted 作为参数。对于元素或模式列表中的每个项目,如果需要替换,则会执行替换。

输出:

Uncleaned:  <title>My example: <strong>A text %very% $clean!!</strong></title>
1st clean:  My example: A text %very% $clean!!
2nd clean:  My example: A text very clean

解决方案 17:

我使用的方法可能不太有效,但它非常简单。我可以使用切片和格式化一次性删除不同位置的多个字符。以下是示例:

words = "things"
removed = "%s%s" % (words[:3], words[-1:])

这将导致“removed”保留单词“this”。

格式化对于在打印字符串中途打印变量非常有用。它可以使用%后跟变量的数据类型来插入任何数据类型;所有数据类型都可以使用%s,浮点数(又称小数)和整数可以使用%d

切片可用于对字符串进行复杂的控制。当我输入words[:3]时,它允许我选择字符串中从开头(冒号在数字之前,这意味着“从开头到”)到第 4 个字符(包括第 4 个字符)的所有字符。3 等于第 4 个位置的原因是 Python 从 0 开始。然后,当我输入word[-1:]时,它意味着从倒数第二个字符到末尾(冒号在数字后面)。输入 -1 将使 Python 从最后一个字符而不是第一个字符开始计数。同样,Python 将从 0 开始。所以,word[-1:]基本上意味着“从倒数第二个字符到字符串的末尾”。

因此,通过切掉我想要删除的字符之前的字符和之后的字符并将它们夹在一起,我可以删除不需要的字符。把它想象成一根香肠。中间很脏,所以我想把它去掉。我只需切掉我想要的两端,然后将它们放在一起,中间不需要的部分就行了。

如果我想删除多个连续的字符,我只需在 [] (切片部分)中移动数字即可。或者,如果我想从不同位置删除多个字符,我可以一次将多个切片夹在一起。

例子:

 words = "control"
 removed = "%s%s" % (words[:2], words[-2:])

删除等于‘酷’。

words = "impacts"
removed = "%s%s%s" % (words[1], words[3:5], words[-1])

删除等于‘macs’。

在这种情况下,[3:5]表示位置3 处的字符到位置5 处的字符(不包括最后位置处的字符)。

请记住,Python 从 0 开始计数,因此您也需要这样做。

解决方案 18:

在 Python 3.5 中

例如,

os.rename(file_name, file_name.translate({ord(c): None for c in '0123456789'}))

从字符串中删除所有数字

解决方案 19:

以下内容已在本帖中解释过。我只是将其汇总起来作为答案。

"".join(filter(lambda x: x not in " ?.!/;:", line))   

解决方案 20:

这个怎么样:

def text_cleanup(text):
    new = ""
    for i in text:
        if i not in " ?.!/;:":
            new += i
    return new

解决方案 21:

下面一个..没有使用正则表达式概念..

ipstring ="text with symbols!@#$^&*( ends here"
opstring=''
for i in ipstring:
    if i.isalnum()==1 or i==' ':
        opstring+=i
    pass
print opstring

解决方案 22:

递归拆分:
s=字符串;chars=要删除的字符

def strip(s,chars):
if len(s)==1:
    return "" if s in chars else s
return strip(s[0:int(len(s)/2)],chars) +  strip(s[int(len(s)/2):len(s)],chars)

例子:

print(strip("Hello!","lo"))    #He!

解决方案 23:

您可以使用 re 模块的正则表达式替换。使用 ^ 表达式可以让您从字符串中准确选择所需的内容。

    import re
    text = "This is absurd!"
    text = re.sub("[^a-zA-Z]","",text) # Keeps only Alphabets
    print(text)

输出结果为“Thisisabsurd”。只有 ^ 符号后指定的内容才会出现。

解决方案 24:

# 对于目录中的每个文件,重命名文件名

   file_list = os.listdir (r"D:DevPython")

   for file_name in file_list:

       os.rename(file_name, re.sub(r'd+','',file_name))

解决方案 25:

即使下面的方法也有效

line = "a,b,c,d,e"
alpha = list(line)
        while ',' in alpha:
            alpha.remove(',')
finalString = ''.join(alpha)
print(finalString)

输出:abcde

解决方案 26:

string 方法replace不会修改原始字符串。它保留原始字符串不变,并返回修改后的副本。

你想要的是类似这样的东西:line = line.replace(char,'')

def replace_all(line, )for char in line:
    if char in " ?.!/;:":
        line = line.replace(char,'')
    return line

但是,每次删除一个字符时都创建一个新字符串是非常低效的。我建议这样做:

def replace_all(line, baddies, *):
    """
    The following is documentation on how to use the class,
    without reference to the implementation details:

    For implementation notes, please see comments begining with `#`
    in the source file.

    [*crickets chirp*]

    """

    is_bad = lambda ch, baddies=baddies: return ch in baddies
    filter_baddies = lambda ch, *, is_bad=is_bad: "" if is_bad(ch) else ch
    mahp = replace_all.map(filter_baddies, line)
    return replace_all.join('', join(mahp))

    # -------------------------------------------------
    # WHY `baddies=baddies`?!?
    #     `is_bad=is_bad`
    # -------------------------------------------------
    # Default arguments to a lambda function are evaluated
    # at the same time as when a lambda function is
    # **defined**.
    #
    # global variables of a lambda function
    # are evaluated when the lambda function is
    # **called**
    #
    # The following prints "as yellow as snow"
    #
    #     fleece_color = "white"
    #     little_lamb = lambda end: return "as " + fleece_color + end
    #
    #     # sometime later...
    #
    #     fleece_color = "yellow"
    #     print(little_lamb(" as snow"))
    # --------------------------------------------------
replace_all.map = map
replace_all.join = str.join

解决方案 27:

如果您希望字符串仅包含使用 ASCII 代码的字符,则可以使用以下代码:

for char in s:
    if ord(char) < 96 or ord(char) > 123:
        s = s.replace(char, "")

它将删除除 a....z 之外的所有字符,甚至大写字母。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   657  
  如何借鉴华为IPD体系优化企业研发?在当今竞争激烈的市场环境中,企业要想保持技术领先和产品竞争力,必须拥有一套高效且严谨的研发管理体系。华为作为全球领先的ICT解决方案提供商,其集成产品开发(IPD, Integrated Product Development)体系与质量管理体系(如ISO 9000系列)的融合实践,...
IPD项目管理   15  
  IPD流程图的7种经典绘制方法详解在产品开发领域,集成产品开发(Integrated Product Development,简称IPD)流程被广泛应用,以提高产品开发的效率和质量。IPD流程图作为这一流程的可视化工具,其绘制方法至关重要。本文将详细介绍七种经典的IPD流程图绘制方法,帮助项目管理人员和团队更好地理解和...
IPD研发管理体系   18  
  IPD流程:企业创新管理的核心引擎在当今快速变化的市场环境中,企业要想持续保持竞争力,就必须不断进行创新。而IPD(Integrated Product Development,集成产品开发)流程作为一种先进的产品开发管理模式,正逐渐成为众多企业提升创新能力、加速产品上市速度、降低开发成本的重要选择。本文将深入探讨IP...
IPD管理   18  
  IPD流程与传统产品开发流程的概述在产品开发领域,企业不断寻求高效、系统的管理方法以确保产品能够顺利从概念转化为市场成功的产品。集成产品开发(Integrated Product Development,简称IPD)流程与传统产品开发流程是两种截然不同的管理理念和方法。传统产品开发流程往往以职能部门为核心,各部门按顺序...
IPD流程中PDCP是什么意思   16  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用