首页 文章

从Python中的字符串中删除特定字符

提问于
浏览
393

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

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

我该怎么做呢?

25 回答

  • 507

    Python中的字符串是不可变的(不能更改) . 因此, line.replace(...) 的效果只是创建一个新字符串,而不是更改旧字符串 . 您需要将其重新绑定(分配)为 line ,以使该变量获取新值,并删除这些字符 .

    而且,你这样做的方式相对较慢 . 对于经验丰富的pythonator来说,这也有点令人困惑,他们会看到一个双重嵌套的结构,并想一想更复杂的事情正在发生 .

    从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中,字符串是Unicode . 你将不得不翻译一点点 . kevpie在其中一个答案中提到了这一点,并在documentation for str.translate中注明了这一点 .

    调用Unicode字符串的 translate 方法时,无法传递上面使用的第二个参数 . 您也无法将 None 作为第一个参数传递,甚至不能传递 string.maketrans 的转换表 . 而是将字典作为唯一参数传递 . 这个字典将字符的序数值(即调用它们的ord的结果)映射到应该替换它们的字符的序数值,或者对于我们有用的 None 来表示它们应该被删除 .

    所以要用Unicode字符串做上面的舞蹈,你会称之为

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

    这里dict.fromkeysmap用于简洁地生成包含的字典

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

    更简单,如another answer puts it,创建字典:

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

    *为了与早期的Pythons兼容,您可以创建一个"null"转换表来代替 None

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

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

  • 17

    我在这里忽略了这一点,还是仅仅是以下内容:

    >>> string = "ab1cd1ef"
    >>> string.replace("1","")
    'abcdef'
    >>>
    

    把它放在一个循环中:

    >>>
    >>> a = "a!b@c#d$"
    >>> b = "!@#$"
    >>> for char in b:
    ...     a = a.replace(char,"")
    ...
    >>> print a
    abcd
    >>>
    
  • 17
    >>> line = "abc#@!?efg12;:?"
    >>> ''.join( c for c in line if  c not in '?:!/;' )
    'abc#@efg12'
    
  • 33

    提问者几乎拥有它 . 像Python中的大多数东西一样,答案比你想象的要简单 .

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

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

  • 4

    对于字符串中 only allowing certain characters 的反向要求,可以使用带有set complement运算符 [^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'
    

    the python regular expression documentation

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

  • 17

    使用Python 3.5中的re.sub轻松实现

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

    示例

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

    解释

    regular expressions(正则表达式)中, | 是逻辑OR和 \ 转义空格和特殊字符,可能是实际的正则表达式命令 . sub 代表替代 .

  • 1
    line = line.translate(None, " ?.!/;:")
    
  • 10
    >>> s = 'a1b2c3'
    >>> ''.join(c for c in s if c not in '123')
    'abc'
    
  • 0

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

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

    我很惊讶没有人建议使用内置的 filter 功能 .

    import operator
        import string # only for the example you could use a custom string
    
        s = "1212edjaq"
    

    假设我们要过滤掉所有不是数字的东西 . 使用过滤器内置方法"...is equivalent to the generator expression (item for item in iterable if function(item))" [Python 3 Builtins: 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"
    

    我不确定 filter 在效率方面是如何排名的,但是在做列表推导等时知道如何使用是一件好事 .

    UPDATE

    从逻辑上讲,由于过滤器的工作原理,你也可以使用列表理解,从我所读到的它应该更有效率,因为lambdas是编程功能世界的华尔街对冲基金经理 . 另一个优点是它是一个不需要任何进口的单线程 . 例如,使用上面定义的相同字符串'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])
    
  • 14

    使用filter,你只需要一行

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

    这对待了string as a iterable,如果 lambda 返回 True ,则检查每个字符:

    帮助(过滤器)
    有关模块__builtin__中内置函数过滤器的帮助:

    过滤(...)
    filter(function或None,sequence) - > list,tuple或string

    返回函数(item)为true的序列项 . 如果
    function为None,返回true的项 . 如果序列是一个元组
    或字符串,返回相同的类型,否则返回一个列表 .

  • 0
    >>> # Character stripping
    >>> a = '?abcd1234!!'
    >>> t.lstrip('?')
    'abcd1234!!'
    >>> t.strip('?!')
    'abcd1234'
    
  • 3

    这是我的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)
    
  • 170

    以下是实现此任务的一些可能方法:

    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"))
    

    PS:相反使用“? . !/;:”这些例子使用元音...是的,“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
    

    所以看起来try4是这个特定输入中最快的一个 .

  • 1
    #!/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
    
  • 3

    这个怎么样:

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

    您还可以使用函数来使用列表替换不同类型的正则表达式或其他模式 . 有了它,您可以混合正则表达式,字符类和真正基本的文本模式 . 当你需要替换像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和您的列表作为参数不需要 . 对于元素或模式列表中的每个项目,如果需要替换,则将完成 .

    输出:

    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
    
  • 0

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

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

    这将导致'删除'持有'this'这个词 .

    Formatting 对于在打印字符串中途打印变量非常有用 . 它可以使用 % 后跟变量的数据类型插入任何数据类型;所有数据类型都可以使用 %s ,浮点数(也就是小数)和整数可以使用 %d .

    Slicing 可用于对字符串的复杂控制 . 当我输入 words[:3] 时,它允许我从头开始选择字符串中的所有字符(冒号在数字之前,这意味着'from the beginning to')到第4个字符(它包括第4个字符) . 原因3等于直到第4位是因为Python从0开始 . 然后,当我输入 word[-1:] 时,它表示结尾的第二个最后一个字符(冒号位于数字后面) . 设置-1会使Python从最后一个字符开始计数,而不是第一个字符 . 同样,Python将从0开始 . 因此, word[-1:] 基本上意味着'从第二个字符到字符串结尾 .

    因此,通过在我要移除的角色之前切掉角色,然后将角色夹在一起,我可以删除不需要的角色 . Think of it like a sausage. 在中间它很脏,所以我想摆脱它 . 我只是切断了我想要的两端,然后把它们放在一起,中间没有不需要的部分 .

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

    例子:

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

    removed 等于'cool' .

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

    removed 等于'macs' .

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

    请记住,Python从0开始计数,因此您也需要 .

  • 0

    你必须重新分配你的str变量:

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

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

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

    在Python 3.5中

    例如 . ,

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

    从字符串中删除所有数字

  • 0

    你可以用套装

    charlist = list(set(string.digits+string.ascii_uppercase) - set('10IO'))
        return ''.join([random.SystemRandom().choice(charlist) for _ in range(passlen)])
    
  • 0

    试试这个:

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

    这种方法在python 3.5.2中运行良好

  • 1

    递归拆分:s = string; 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!
    
  • 7

    即使是以下方法也适用

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

    输出>> abcde

相关问题