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?
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.
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
>>>
>>> line = "abc#@!?efg12;:?"
>>> ''.join( c for c in line if c not in '?:!/;' )
'abc#@efg12'
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.
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.
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.
>>> s = 'a1b2c3'
>>> ''.join(c for c in s if c not in '123')
'abc'
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,'')
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])
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.
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)
>>> # Character stripping
>>> a = '?abcd1234!!'
>>> t.lstrip('?')
'abcd1234!!'
>>> t.strip('?!')
'abcd1234'
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.
#!/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
Que pensez-vous de ceci:
def text_cleanup(text):
new = ""
for i in text:
if i not in " ?.!/;:":
new += i
return new
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
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.
vous devez réassigner votre variable str:
for char in line:
if char in " ?.!/;:":
line = line.replace(char,'')
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
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
vous pouvez utiliser set
charlist = list(set(string.digits+string.ascii_uppercase) - set('10IO'))
return ''.join([random.SystemRandom().choice(charlist) for _ in range(passlen)])
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
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!
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