Supprimer des caractères spécifiques d'une chaîne en Python

j'essaie de supprimer des caractères spécifiques d'une chaîne en utilisant Python. C'est le code que j'utilise actuellement. Malheureusement, il semble ne rien faire à la chaîne.

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

Comment dois-je procéder?

385
demandé sur serv-inc 2010-10-15 07:46:21

25 réponses

les chaînes en Python sont immuable (ne peut pas être changé). De ce fait, l'effet de line.replace(...) est tout simplement de créer une nouvelle chaîne, plutôt que de changer l'ancien. Vous devez rebind (assignez) à line afin que cette variable prenne la nouvelle valeur, avec ces caractères supprimés.

Aussi, la façon dont vous le faites est va être lente, relativement. Il est également susceptible d'être un peu déroutant pour les pythonateurs expérimentés, qui verront une structure doublement imbriquée et penseront un instant que quelque chose de plus compliqué se passe.

à partir de python 2.6 et plus récent Python 2.X versions *, vous pouvez utiliser à la place str.translate , (mais lisez pour Python 3 différences):

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

ou remplacement de l'expression régulière par re.sub

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

les caractères entre parenthèses constituent une classe de caractères . Tous les caractères de line qui sont dans cette classe sont remplacés par le second paramètre de sub : une chaîne vide.

en Python 3, les chaînes sont Unicode. Vous devrez traduire un peu différemment. kevpie mentionne cela dans un commentaire sur l'une des réponses, et il est noté dans la documentation pour str.translate .

lorsque vous appelez la méthode translate d'une chaîne Unicode, vous ne pouvez pas passer le second paramètre que nous avons utilisé ci-dessus. Vous ne pouvez pas non plus passer None comme premier paramètre, ni même une table de traduction de string.maketrans . Au lieu de cela, vous passez un dictionnaire comme le seul paramètre. Ce dictionnaire présente les valeurs ordinales des caractères (c. - à-d. le résultat de l'appel ord sur eux) les valeurs ordinales des personnages qui doivent les remplacer, ou-utilement pour nous- None pour indiquer qu'ils doivent être supprimés.

donc pour faire la danse ci-dessus avec une corde Unicode vous appelleriez quelque chose comme

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

ici dict.fromkeys et map sont utilisés pour générer succinctement un dictionnaire contenant

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

Even plus simple, comme une autre réponse le met , créer le dictionnaire en place:

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

* pour la compatibilité avec les Pythons précédents, vous pouvez créer une table de traduction" null " pour passer à la place de None :

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

ici string.maketrans est utilisé pour créer une table de traduction , qui est juste une chaîne contenant les caractères avec des valeurs ordinales de 0 à 255.

493
répondu intuited 2017-05-23 12:34:53

est-ce que je manque le point ici, ou est-ce juste le suivant:

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

mettez-le en boucle:

>>>
>>> a = "a!b@c#d$"
>>> b = "!@#$"
>>> for char in b:
...     a = a.replace(char,"")
...
>>> print a
abcd
>>>
160
répondu gsbabil 2016-09-05 21:19:15
>>> line = "abc#@!?efg12;:?"
>>> ''.join( c for c in line if  c not in '?:!/;' )
'abc#@efg12'
31
répondu ghostdog74 2010-10-15 04:18:18

l'asker l'avait presque. Comme la plupart des choses en Python, la réponse est plus simple que vous le pensez.

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

vous ne devez pas faire la chose imbriquée si/pour boucle, mais vous devez vérifier chaque caractère individuellement.

16
répondu mgold 2011-12-14 18:03:11

Pour l'inverse de la condition de seulement permettant de certains personnages dans une chaîne de caractères, vous pouvez utiliser des expressions régulières avec un ensemble opérateur de complément [^ABCabc] . Par exemple, pour supprimer tout sauf ascii lettres, chiffres, et le trait d'Union:

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

à Partir de le python ordinaire de l'expression de la documentation :

caractères qui ne sont pas dans une gamme peut être assorti en complétant ensemble. Si le premier caractère de l'ensemble est '^' , tous les personnages qui ne sont pas dans le jeu sera mis en correspondance. Par exemple, [^5] correspondra tous les caractères sauf '5', et [^^] correspondront à tous les caractères sauf '^' . ^ n'a pas de signification particulière, si ce n'est pas le premier caractère de la définir.

16
répondu cod3monk3y 2014-01-25 22:39:18

pois facile avec re.sub en Python 3.5

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

exemple

>>> import re

>>> line = 'Q: Do I write ;/.??? No!!!'

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

explication

Dans expressions régulières (regex), | est un OU logique et \ s'échappe des espaces et des caractères spéciaux qui pourraient être réels regex commandes. sub signifie substitution.

16
répondu Serge Stroobandt 2018-05-31 14:22:11
line = line.translate(None, " ?.!/;:")
14
répondu Muhammad Alkarouri 2010-10-15 03:59:40
>>> s = 'a1b2c3'
>>> ''.join(c for c in s if c not in '123')
'abc'
10
répondu eatkin 2016-07-01 14:48:17
Les chaînes

sont immuables en Python. La méthode replace renvoie une nouvelle chaîne après le remplacement. Essayez:

for char in line:
    if char in " ?.!/;:":
        line = line.replace(char,'')
7
répondu Greg Hewgill 2010-10-15 03:50:19

j'ai été surpris que personne n'ait encore recommandé l'utilisation de la fonction filtre .

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

    s = "1212edjaq"

dit qu'on veut filtrer tout ce qui n'est pas un nombre. En utilisant la méthode d'intégration de filtre" ...est équivalent à l'expression de générateur (élément pour l'élément dans la fonction iterable if(élément)) "[ Python 3 Builtins: Filter ]

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

en Python 3 ce retourne

    >>  <filter object @ hex>

pour obtenir une chaîne imprimée,

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

je ne suis pas sûr de savoir comment filtre rangs en termes d'efficacité, mais c'est une bonne chose de savoir comment l'utiliser lorsque vous faites des interprétations de la liste.

UPDATE

logiquement, puisque le filtre fonctionne, vous pouvez également utiliser la compréhension de liste et de ce que j'ai lu il est censé être plus efficace parce que lambdas sont le wall street gestionnaires de fonds de couverture de la fonction de programmation du monde. Un autre avantage est qu'il s'agit d'une doublure unique qui ne nécessite aucune importation. Par exemple, en utilisant la même chaîne de caractères 's' définie ci-dessus,

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

C'est ça. Le retour sera une chaîne de caractères de tous les personnages qui sont des chiffres dans la chaîne d'origine.

si vous avez une liste spécifique de caractères acceptables/inacceptables, vous n'avez qu'à ajuster la partie " si " de la liste de compréhension.

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

ou alternativement,

      target_chars = "".join([i for i in s if i not in some_list])
5
répondu Dan Temkin 2017-10-28 22:31:26

utilisant filter , tu n'as besoin que d'une ligne.

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

cela traite la chaîne comme une itérable et vérifie chaque caractère si le lambda retourne 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.
4
répondu serv-inc 2017-10-25 10:54:21

voici ma version compatible Python 2/3. Depuis que l'api de traduction a changé.

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)
3
répondu Bryce Guinta 2016-08-03 16:07:26
>>> # Character stripping
>>> a = '?abcd1234!!'
>>> t.lstrip('?')
'abcd1234!!'
>>> t.strip('?!')
'abcd1234'
3
répondu Arihant Bansal 2017-10-31 08:06:00

voici quelques façons possibles d'accomplir cette tâche:

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: au lieu d'utiliser " ?.!/;:" les exemples utilisent les voyelles... et oui, "murciélago" est le mot espagnol pour dire chauve-souris... drôle de mot comme il contient toutes les voyelles :)

PS2: si vous êtes intéressé par la performance, vous pouvez mesurer ces tentatives avec un code simple comme:

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

Dans ma boîte, vous obtiendrez:

attempt1 2.2334518376057244
attempt2 1.8806643818474513
attempt3 7.214925774955572
attempt4 1.7271184513757465

So il semble que la tentative 4 soit la plus rapide pour cette entrée particulière.

2
répondu BPL 2018-07-22 13:36:32
#!/usr/bin/python
import re

strs = "how^ much for{} the maple syrup? .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
1
répondu pkm 2014-05-25 09:34:51

Que pensez-vous de ceci:

def text_cleanup(text):
    new = ""
    for i in text:
        if i not in " ?.!/;:":
            new += i
    return new
1
répondu Wariat 2015-03-24 07:53:01

Vous pouvez également utiliser une fonction, afin de le remplacer par expression régulière ou un autre modèle, avec l'utilisation d'une liste. Avec cela, vous pouvez mélanger l'expression régulière, la classe de caractères, et vraiment le motif de texte de base. C'est vraiment utile quand vous avez besoin de remplacer beaucoup d'éléments comme HTML.

*NB: fonctionne avec 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)

dans la fonction string_cleanup, il prend votre chaîne x et votre liste notwanted comme argument. Pour chaque élément dans la liste d'éléments ou de modèle, si un remplaçant est nécessaire, il sera fait.

La sortie:

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
1
répondu Djidiouf 2015-08-11 06:36:14

ma méthode que j'utiliserais ne fonctionnerait probablement pas aussi efficacement, mais elle est massivement simple. Je peux supprimer plusieurs caractères à différentes positions à la fois, en utilisant le découpage et le formatage. Voici un exemple:

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

il en résulte que le mot "ceci" est "supprimé".

formatage peut être très utile pour imprimer des variables à mi-chemin d'une chaîne d'impression. Il peut insérer n'importe quel type de données en utilisant un % suivi du type de données de la variable; tous les types de données peuvent utiliser %s , et les flotteurs (alias décimales) et les entiers peuvent utiliser %d .

tranchage peut être utilisé pour le contrôle complexe sur les cordes. Quand je mets mots [: 3] , il me permet de sélectionner tous les caractères dans la chaîne de début (le deux-points est avant le nombre, ce qui signifie 'À partir du début ') pour le 4e caractère (il comprend le 4e caractère). La raison pour laquelle 3 égale jusqu'à la 4ème position est que Python commence à 0. Puis, quand je mets mot[-1:] , il signifie le 2ème dernier caractère à la fin (le deux-points est derrière le nombre). Putting -1 va faire Python Compter à partir du dernier caractère, plutôt que le premier. Encore une fois, Python commencera à 0. Ainsi, mot[-1:] signifie " de l'avant-dernier caractère à la fin de la chaîne.

Donc, en coupant les caractères avant le caractère que je veux supprimer et les caractères après et prendre en sandwich ensemble, je peux supprimer le caractère redondant. Pensez-y comme une saucisse. Dans le milieu, il est sale, donc je veux m'en débarrasser. Je coupe simplement les deux extrémités que je veux puis les mettre ensemble sans la partie non désirée au milieu.

si je veux supprimer plusieurs caractères consécutifs, je change simplement les nombres autour dans la [] (partie tranchant). Ou si je veux supprimer plusieurs caractères de différentes positions, je peux simplement sandwich ensemble plusieurs tranches à la fois.

exemples:

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

supprimé égale "cool".

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

supprimé égale "macs".

dans ce cas, [3:5] signifie caractère à position 3 à travers le caractère à position 5 (à l'exclusion du caractère à la position finale).

Souvenez-vous, Python commence à compter à 0 , de sorte que vous aurez besoin.

1
répondu oisinvg2001 2016-06-10 19:30:39

vous devez réassigner votre variable str:

for char in line:
if char in " ?.!/;:":
    line = line.replace(char,'')
1
répondu Anastasia Churyk 2018-07-13 10:28:19

en dessous d'un.. avec l'aide de l'expression régulière concept..

ipstring ="text with symbols!@#$^&*( ends here"
opstring=''
for i in ipstring:
    if i.isalnum()==1 or i==' ':
        opstring+=i
    pass
print opstring
0
répondu Sadheesh 2015-05-10 15:06:31

En Python 3.5

par exemple,

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

pour supprimer tout le numéro de la chaîne de caractères

0
répondu BonieSV 2017-01-07 01:25:05

vous pouvez utiliser set

    charlist = list(set(string.digits+string.ascii_uppercase) - set('10IO'))
    return ''.join([random.SystemRandom().choice(charlist) for _ in range(passlen)])
0
répondu Xu Zhenlei 2017-02-17 02:07:28

essayez celui-ci:

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

cette méthode fonctionne bien en python 3.5.2

0
répondu Joseph Lee 2017-10-31 08:01:42

Récursive split: s = chaîne ; chars = chars pour supprimer

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)

exemple:

print(strip("Hello!","lo"))    #He!
0
répondu matt 2018-01-13 14:16:57

même l'approche ci-dessous fonctionne

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

sortie > > abcde

0
répondu M2skills 2018-01-27 07:04:20