在Python中替换字符串中的特殊字符

55

我正在使用urllib从网站获取HTML字符串,并需要将文档中的每个单词放入列表中。

以下是我目前拥有的代码。我一直收到错误消息。我也复制了错误消息如下。

import urllib.request

url = input("Please enter a URL: ")

z=urllib.request.urlopen(url)
z=str(z.read())
removeSpecialChars = str.replace("!@#$%^&*()[]{};:,./<>?\|`~-=_+", " ")

words = removeSpecialChars.split()

print ("Words list: ", words[0:20])

这里有一个错误。

Please enter a URL: http://simleyfootball.com
Traceback (most recent call last):
  File "C:\Users\jeremy.KLUG\My Documents\LiClipse Workspace\Python Project 2\Module2.py", line 7, in <module>
    removeSpecialChars = str.replace("!@#$%^&*()[]{};:,./<>?\|`~-=_+", " ")
TypeError: replace() takes at least 2 arguments (1 given)
6个回答

124

一种方法是使用re.sub,这是我首选的方法。

import re
my_str = "hey th~!ere"
my_new_string = re.sub('[^a-zA-Z0-9 \n\.]', '', my_str)
print my_new_string

输出:

hey there

另一种方法是使用re.escape:

import string
import re

my_str = "hey th~!ere"

chars = re.escape(string.punctuation)
print re.sub('['+chars+']', '',my_str)

输出:

hey there

关于Python参数风格的一个小提示:根据PEP-8,参数应该是remove_special_chars而不是removeSpecialChars

另外,如果您想保留空格,请将[^a-zA-Z0-9 \n\.]更改为[^a-zA-Z0-9\n\.]


1
+1 明显是最快和最好的答案 它处理每种情况,如果给出奇怪的 utf8 字符,翻译将不会做任何事情, 使用负正则表达式 [^...] 的 re.sub 更安全。 - thibault ketterer
如何使用 re.sub 替换字符 `? - vineeshvs
2
非常有帮助的答案,但是在最后一行,您难道不是想说使用 [^a-zA-Z0-9\n.] 将删除空格吗? - radouxju

54

str.replace不是你想要做的事情的正确函数(除了它被错误地使用之外)。 你想用空格替换任何一组字符,而不是将整组字符替换为单个空格(后者就是replace所做的)。 你可以像这样使用translate:

removeSpecialChars = z.translate ({ord(c): " " for c in "!@#$%^&*()[]{};:,./<>?\|`~-=_+"})

这将创建一个映射,将你特殊字符列表中的每个字符都映射到一个空格,然后在字符串上调用 translate() 方法,用空格替换特殊字符集中的每个字符。

你确定正则表达式比翻译函数更高效吗?翻译函数内部可能使用了正则表达式? - Vreddhi Bhat
2
使用 ord 很好!否则,在特殊字符上使用 str.translate 不会有任何作用。 - bergercookie
谢谢!这个答案救了我的一天。 - Jinhua Wang
请注意,此代码将替换字符集中的任何内容,而此答案将替换不符合正则表达式匹配的任何内容。如果目标是使字符串在给定上下文中“安全”,后者可能是更安全的方法。 - AdamAL

8
您需要在变量 z 上调用 replace 而不是 str ,因为您想要替换位于字符串变量 z 中的字符。
removeSpecialChars = z.replace("!@#$%^&*()[]{};:,./<>?\|`~-=_+", " ")

但这样不会起作用,因为replace只查找子字符串,您最有可能需要使用正则表达式模块resub函数:

import re
removeSpecialChars = re.sub("[!@#$%^&*()[]{};:,./<>?\|`~-=_+]", " ", z)

不要忘记[],它表示需要替换的一组字符。


这是错误的。方括号内的 [] 需要转义,- 必须放在最后,否则它将成为一个范围。请改为使用 re.sub("[!@#$%^&*(){};:,./<>?|`~=_[]-]", " ", z)。 - Majte

0
您可以按照以下方式将特殊字符替换为所需的字符,代码如下,
import string
specialCharacterText = "H#y #@w @re &*)?"
inCharSet = "!@#$%^&*()[]{};:,./<>?\|`~-=_+\""
outCharSet = "                               " #corresponding characters in inCharSet to be replaced
splCharReplaceList = string.maketrans(inCharSet, outCharSet)
splCharFreeString = specialCharacterText.translate(splCharReplaceList)

0

替换操作针对特定字符串进行,因此您需要像这样调用它

removeSpecialChars = z.replace("!@#$%^&*()[]{};:,./<>?\|`~-=_+", " ")

但这可能不是你需要的,因为这将查找一个包含所有字符并按相同顺序排列的单个字符串。正则表达式可以做到这一点,正如Danny Michaud所指出的那样。
另外,你可能想要寻找BeautifulSoup,它是一个用于解析混乱的HTML格式文本的库,就像你通常从网站上抓取的文本一样。

我必须只使用Python中包含的库。有没有正则表达式可以完成我想做的事情? - user2363217
这取决于你是否要处理英文文本、包含重音符号、umlauts等外语单词、数字、货币符号等文本。没有通用的正则表达式可以"清理东西",需要具体说明你所需的内容。 - Pavel

0

翻译似乎更快:

N=100000,30个特殊字符,字符串长度=70

替换:0.3251810073852539 re.sub:0.2859320640563965 翻译:0.12320685386657715


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接