我试图使用Python从字符串中删除特定字符。这是我现在使用的代码。不幸的是,它似乎对字符串没有做任何事情。
for char in line:
if char in " ?.!/;:":
line.replace(char,'')
我如何正确地做到这一点?
我试图使用Python从字符串中删除特定字符。这是我现在使用的代码。不幸的是,它似乎对字符串没有做任何事情。
for char in line:
if char in " ?.!/;:":
line.replace(char,'')
我如何正确地做到这一点?
字符串在Python中是不可变的。replace方法在替换后返回一个新字符串。试一试:
for char in line:
if char in " ?.!/;:":
line = line.replace(char,'')
这与您的原始代码相同,只是在循环中添加了对line的赋值。
注意,字符串replace()方法会替换字符串中出现的所有字符,因此可以对想要删除的每个字符使用replace(),而不是遍历字符串中的每个字符,这样做会更好。
Python中的字符串是不可变的(不能更改)。因此,line.replace(…)的作用只是创建一个新字符串,而不是更改旧字符串。您需要将其重新绑定(赋值)到行,以便使该变量具有新的值,并删除那些字符。
而且,你做的方法相对来说会比较慢。对于有经验的python编程者来说,这也可能会有点困惑,他们会看到一个双嵌套结构,并认为正在发生更复杂的事情。
从Python 2.6和更新的Python 2开始。x版本*,你可以使用str.translate,(见下面的Python 3答案):
line = line.translate(None, '!@#$')
或者用re.sub替换正则表达式
import re
line = re.sub('[!@#$]', '', 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.fromkeys和map简洁地生成包含
{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兼容,你可以创建一个“null”转换表来代替None:
import string
line = line.translate(string.maketrans('', ''), '!@#$')
这里的字符串。Maketrans用于创建一个转换表,它只是一个包含序数为0到255的字符的字符串。
>>> line = "abc#@!?efg12;:?"
>>> ''.join( c for c in line if c not in '?:!/;' )
'abc#@efg12'
我是不是错过了重点,或者仅仅是以下几点:
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"
提问者几乎就说到了。像Python中的大多数事情一样,答案比您想象的要简单。
>>> line = "H E?.LL!/;O:: "
>>> for char in ' ?.!/;:':
... line = line.replace(char,'')
...
>>> print line
HELLO
你不需要做嵌套的if/for循环,但你确实需要单独检查每个字符。
对于只允许字符串中某些字符的相反要求,可以使用带有集补操作符[^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'以外的任何字符,[^^]将匹配除 “^”。的第一个字符没有特殊意义 集。
#!/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
这个怎么样:
def text_cleanup(text):
new = ""
for i in text:
if i not in " ?.!/;:":
new += i
return new
下面一个. .没有使用正则表达式的概念..
ipstring ="text with symbols!@#$^&*( ends here"
opstring=''
for i in ipstring:
if i.isalnum()==1 or i==' ':
opstring+=i
pass
print opstring
您还可以使用函数来替换不同类型的正则表达式或使用列表的其他模式。这样,您就可以混合正则表达式、字符类和真正基本的文本模式。当您需要替换大量元素(如HTML元素)时,它非常有用。
*注意:适用于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
我使用的方法可能没有那么有效,但它非常简单。我可以一次删除不同位置的多个字符,使用切片和格式化。 这里有一个例子:
words = "things"
removed = "%s%s" % (words[:3], words[-1:])
这将导致在“removed”中保留单词“This”。
格式化对于在打印字符串的中途打印变量非常有用。它可以插入任何数据类型,使用%后跟变量的数据类型;所有数据类型都可以使用%s,浮点数(即小数)和整数可以使用%d。
Slicing can be used for intricate control over strings. When I put words[:3], it allows me to select all the characters in the string from the beginning (the colon is before the number, this will mean 'from the beginning to') to the 4th character (it includes the 4th character). The reason 3 equals till the 4th position is because Python starts at 0. Then, when I put word[-1:], it means the 2nd last character to the end (the colon is behind the number). Putting -1 will make Python count from the last character, rather than the first. Again, Python will start at 0. So, word[-1:] basically means 'from the second last character to the end of the string.
因此,通过切断我想要删除的字符之前的字符和之后的字符,并将它们夹在一起,我可以删除不需要的字符。把它想象成香肠。中间是脏的,所以我想把它处理掉。我只是把我想要的两端剪掉,然后把它们放在一起,中间没有多余的部分。
如果我想删除多个连续字符,我只需在[](切片部分)中移动数字。或者,如果我想从不同的位置删除多个字符,我可以简单地一次将多个切片夹在一起。
例子:
words = "control"
removed = "%s%s" % (words[:2], words[-2:])
remove = 'cool'。
words = "impacts"
removed = "%s%s%s" % (words[1], words[3:5], words[-1])
remove = 'macs'。
在本例中,[3:5]表示位置3到位置5的字符(不包括最后位置的字符)。
记住,Python从0开始计数,所以你也需要这样做。
这是我的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)
令我惊讶的是,还没有人推荐使用内置的过滤功能。
import operator
import string # only for the example you could use a custom string
s = "1212edjaq"
假设我们想过滤掉所有不是数字的东西。使用过滤器内置方法“…等效于生成器表达式(item for item在可迭代if函数(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"
我不确定过滤器在效率方面的排名,但在做列表理解等时,知道如何使用是一件好事。
更新
从逻辑上讲,既然过滤器可以工作,你也可以使用列表理解,从我所读到的,它应该更有效,因为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])
在Python 3.5中
例如,
os.rename(file_name, file_name.translate({ord(c): None for c in '0123456789'}))
从字符串中删除所有数字
即使是下面的方法也是有效的
line = "a,b,c,d,e"
alpha = list(line)
while ',' in alpha:
alpha.remove(',')
finalString = ''.join(alpha)
print(finalString)
输出:中的
用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代表替换,在这种情况下是空字符串”。
使用过滤器,你只需要一行
line = filter(lambda char: char not in " ?.!/;:", line)
这将字符串视为可迭代对象,如果lambda返回True,则检查每个字符:
> > >帮助(过滤器) 模块__builtin__中内置函数过滤器的帮助: 过滤器(…) filter(function或None, sequence) ->列表、元组或字符串 返回函数(item)为true的序列项。如果 函数为None,返回为true的项。If sequence是一个元组 或者字符串,返回相同的类型,否则返回一个列表。
试试这个:
def rm_char(original_str, need2rm):
''' Remove charecters in "need2rm" from "original_str" '''
return original_str.translate(str.maketrans('','',need2rm))
这个方法在python3中很有效
递归分割: 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!
这里有一些可能的方法来完成这个任务:
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
因此,对于这个特定的输入,尝试4似乎是最快的。
你可以使用re模块的正则表达式替换。使用^表达式可以准确地从字符串中选择想要的内容。
import re
text = "This is absurd!"
text = re.sub("[^a-zA-Z]","",text) # Keeps only Alphabets
print(text)
输出结果将是“这是荒谬的”。只有在^符号之后指定的内容才会出现。
#对于目录中的每个文件,重命名文件名
file_list = os.listdir (r"D:\Dev\Python")
for file_name in file_list:
os.rename(file_name, re.sub(r'\d+','',file_name))
字符串方法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
如果你想让你的字符串只允许使用ASCII码,你可以使用这段代码:
for char in s:
if ord(char) < 96 or ord(char) > 123:
s = s.replace(char, "")
它将删除....以外的所有字符Z是大写的。