HOWTO · Python
在 Python 中删除字符串中的特殊字符
本教程介绍了如何在 Python 中删除字符串中的所有特殊字符。
本页内容
要从 Python 字符串中删除字符,先确定要保留哪些字符。使用字符串推导式或配合 str.isalnum() 的 filter(),可以保留 Unicode 字母和数字;正则表达式可以保留空格;str.translate() 则可针对指定字符集进行处理。下面的示例使用 "Hey! What's up bro?" 来清楚展示每条规则。每段代码都会自行定义输入并打印转换后的字符串,因此可以分别运行这些方法。
明确哪些字符算作特殊字符
“特殊字符”没有统一的定义。它可能仅指标点符号,也可能包括标点和空白字符,或者指 ASCII 字母和数字以外的所有字符。应根据清理后字符串的用途来选择规则:显示名称可能需要保留空格,而紧凑标识符可能不需要。
Python 字符串采用 Unicode。str.isalnum() 可以识别 Unicode 字母和数字,因此会保留 é 和 中 这类字符。相比之下,使用 [a-zA-Z0-9] 编写的模式只涵盖 ASCII 字母和数字。因此,除非为这些方法指定相同的字符规则,否则它们会产生不同的结果。
使用推导式删除非字母数字字符
当结果只应包含字母和数字时,可以使用字符串推导式配合 str.isalnum()。str.join() 会将保留下来的字符组合成一个新字符串。这条规则也会删除空格和标点符号。
original = "Hey! What's up bro?"
cleaned = "".join(char for char in original if char.isalnum())
print(cleaned)
HeyWhatsupbro
该谓词会保留 Unicode 字母和数字,也会保留 ASCII 字符。例如,é 这样的字母会被保留;空格、撇号和其他标点符号则会被删除。
使用 filter() 筛选字符
内置函数 filter() 会将谓词应用于每个字符,并返回一个迭代器,其中包含谓词结果为真的字符。传入 str.isalnum 会像推导式一样保留 Unicode 字母和数字,str.join() 则会将迭代器转换回字符串。与推导式一样,空白字符也会被删除。
original = "Hey! What's up bro?"
kept = filter(str.isalnum, original)
cleaned = "".join(kept)
print(cleaned)
HeyWhatsupbro
如果想重复使用某个谓词,或者已经定义了谓词,可以使用 filter()。对于这种简单的字符串转换,推导式能以更简洁的方式表达相同规则。
使用 str.translate() 删除指定字符集
如果已知要删除哪些字符,并希望保留其他所有字符,可以使用 str.translate()。str.maketrans() 会建立一张映射表,将选定字符映射为删除操作。下面的字符集会删除常见的 ASCII 标点;空格和未列出的字符都会保持不变。
original = "Hey! What's up bro?"
characters_to_remove = "!@#$%^&*()_-+=<>,./?;:'\"[]{}\\|`~"
table = str.maketrans("", "", characters_to_remove)
cleaned = original.translate(table)
print(cleaned)
Hey Whats up bro
根据输入内容调整 characters_to_remove 中的字符。这个方法不会删除所有可能被视为标点的字符:未列出的字符(包括非 ASCII 标点)仍会保留在结果中。
使用正则表达式删除字符
使用 re.sub() 可以替换所有与模式匹配的字符。这个模式只保留 ASCII 字母和数字,因此空格和标点都会被删除。文章配图展示的也是这条规则。字母和数字范围仅适用于 ASCII;如果文本包含这些范围以外的字母,应使用能处理 Unicode 的规则。
import re
original = "Hey! What's up bro?"
pattern = r"[^a-zA-Z0-9]"
cleaned = re.sub(pattern, "", original)
print(cleaned)
HeyWhatsupbro
所提供的运行证据记录了此示例生成上方所示输出。若要保留空白字符,可像 r"[^a-zA-Z0-9\s]" 这样将 \s 加入允许保留的字符集合。Python 正则表达式的字符类和标志可以表达其他规则,但应确认所选模式符合数据所用的语言和字符。
使用 map() 和 lambda 转换字符
map() 会将函数应用于每个字符,并返回一个迭代器。lambda 可以在字符是 Unicode 字母、数字或空白字符时返回原字符,其他字符则返回空字符串。将这些结果连接起来即可生成清理后的字符串;此规则会保留空白字符,包括制表符和换行符。
original = "Hey! What's up bro?"
cleaned = "".join(
map(lambda char: char if char.isalnum() or char.isspace() else "", original)
)
print(cleaned)
Hey Whats up bro
当转换逻辑超出简单的保留条件时,这种逐字符处理方式是一种替代方案。如果规则只是保留字母和数字,请改用推导式或 filter() 示例。
选择符合字符规则的方法
- 如果需要直接易读的规则,并且要保留 Unicode 字母和数字、删除空白字符,请使用配合
str.isalnum()的推导式。 - 如果要传入可重复使用的谓词,请使用
filter();示例采用的仍是相同的str.isalnum()规则。 - 如果要删除一组已知字符,同时保留其他所有内容(包括空白字符和未列出的标点),请使用
str.translate()。 - 如果要用模式描述需删除或保留的字符,请使用
re.sub()。示例中的 ASCII 范围会删除空白字符;处理 Unicode 文本或保留空白字符时,应相应调整模式。 - 如果需要逐字符执行转换逻辑,请使用带 lambda 的
map()。示例会保留 Unicode 字母、数字和空白字符。
处理姓名或自然语言文本前,应先决定如何处理重音符号、非拉丁文字和空格。对于标识符或协议规定的输入,应严格遵循文档定义的字符集,不要依赖宽泛的“特殊字符”概念。