从字符串中删除特定的控制字符(\n \r \t)

11

我有很多包含控制字符,如 \n、\t 和 \r 的文本。我需要用一个简单的空格--> " " 来替换它们。最快的方法是什么?谢谢。


显然,正如Python之禅所建议的那样,只有一种方法可以做到这一点;-) - gruszczy
当字符串有多个相邻的这样的字符时,例如 foo\r\nbar,您是想用两个空格替换 \r\n 还是只用一个? - John Machin
我想将它替换为1。 - Hossein
请考虑去除前导和尾随空格。然后请编辑您的问题,以便明确指定您想要什么。 - John Machin
如果你想同时去除字符串前后的空格,请查看这个答案 - Sven Marnach
6个回答

27
我认为最快的方法是使用 str.translate()
import string
s = "a\nb\rc\td"
print s.translate(string.maketrans("\n\t\r", "   "))

打印

a b c d

编辑:由于这又变成了一场关于性能的讨论,这里有一些数字。对于长字符串,translate()比使用正则表达式要快得多:

s = "a\nb\rc\td " * 1250000

regex = re.compile(r'[\n\r\t]')
%timeit t = regex.sub(" ", s)
# 1 loops, best of 3: 1.19 s per loop

table = string.maketrans("\n\t\r", "   ")
%timeit s.translate(table)
# 10 loops, best of 3: 29.3 ms per loop

这大约是40倍的因素。

5
需要注意的是,在Python3中,string.translate和string.makestrans不可用。使用基于re的解决方案似乎更好。 - Senthil Kumaran
@Ignacio: 导入字符串;hasattr(string,'translate'); hasattr(string,'maketrans')如果您执行hasattr(str,'translate')和hasattr(str,'maketrans'),则为False。字符串模块只是一组字符串常量。此外,根据定义和正确使用maketrans的方法应该是bytes.maketrans。谢谢! - Senthil Kumaran

10
您可以尝试使用正则表达式:
import re
regex = re.compile(r'[\n\r\t]')
regex.sub(' ', my_str)

我已经比较了实际性能,看起来使用正则表达式与使用字符串模块的速度一样快。 - Michal Chruszcz
python2.6 timeit.py -s "import string" -s "s = 'a\nb\rc\td'" -s "s.translate(string.maketrans('\n\t\r', ' '))" 10000000 次循环,3 次中的最佳结果:每次循环耗时 0.0235 微秒 - Michal Chruszcz
python2.6 timeit.py -s "import re" -s "regex = re.compile(r'[\n\r\t]')" -s "regex.sub(' ', 'a\nb\rc\td')" 每秒循环10000000次,3次中最佳时间为0.0232微秒 - Michal Chruszcz
1
@Michal - 你是在比较 regex.sub(...)s.translate(string.maketrans(...)) 还是仅仅和 s.translate(preparedTrans) - eumiro
1
@Michal:尝试在一个有7个字符的字符串上这样做是完全没有意义的。请参见我回答中的编辑。 - Sven Marnach
显示剩余2条评论

5
>>> re.sub(r'[\t\n\r]', ' ', '1\n2\r3\t4')
'1 2 3 4'

4
如果您想规范化空格(将一个或多个空格字符的运行替换为单个空格,并剥离前导和尾随空格),可以使用字符串方法来实现:
>>> text = '   foo\tbar\r\nFred  Nurke\t Joe Smith\n\n'
>>> ' '.join(text.split())
'foo bar Fred Nurke Joe Smith'

2

使用正则表达式

re.sub(r'\s+', ' ', '1\n2\r3\t4')

不使用正则表达式

>>> ' '.join('1\n\n2\r3\t4'.split())
'1 2 3 4'
>>>

1

my_string是你想要删除特定控制字符的字符串。 由于Python中的字符串是不可变的,在替换操作之后,你需要将其赋给另一个字符串或重新赋值:

my_string = re.sub(r'[\n\r\t]*', '', my_string)

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