使用python从txt中删除空格
Posted
技术标签:
【中文标题】使用python从txt中删除空格【英文标题】:Removing white space from txt with python 【发布时间】:2016-08-25 18:28:59 【问题描述】:我有一个 .txt 文件(从网站上抓取为预先格式化的文本),其中的数据如下所示:
B, NICKOLAS CT144531X D1026 JUDGE ANNIE WHITE JOHNSON
ANDREWS VS BALL JA-15-0050 D0015 JUDGE EDWARD A ROBERTS
我想删除列之间的所有额外空格(它们实际上是不同数量的空格,而不是制表符)。然后我还想用一些分隔符(制表符或管道,因为数据中有逗号)替换它,如下所示:
ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS
环顾四周,发现最好的选择是使用 regex 或 shlex 进行拆分。两个类似的场景:
Python Regular expression must strip whitespace except between quotes, Remove white spaces from dict : Python.【问题讨论】:
数据列之间是否总是有多个空格? @cricket_007 是的,总是不止一个空格 您不应该使用正则表达式,因为数据在一列中可能有 2 个或更多空格。数据为文本表格式,sp列应由每行字符的位置确定。 【参考方案1】:考虑到至少有两个空格分隔列,您可以这样使用:
lines = [
'B, NICKOLAS CT144531X D1026 JUDGE ANNIE WHITE JOHNSON ',
'ANDREWS VS BALL JA-15-0050 D0015 JUDGE EDWARD A ROBERTS '
]
for line in lines:
parts = []
for part in line.split(' '):
part = part.strip()
if part: # checking if stripped part is a non-empty string
parts.append(part)
print('|'.join(parts))
输入的输出:
B, NICKOLAS|CT144531X|D1026|JUDGE ANNIE WHITE JOHNSON
ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS
【讨论】:
在作为答案发布之前您是否对其进行了测试? 这怎么给ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS
?
想解释一下否决票? @PeterWood 编辑后的代码提供了所需的输出。
基本上,您正在创建一个包含一大堆 ''
的列表,并使用 if 语句跳过它们。此外,part.strip()
被调用了两次,一次用于比较,一次用于添加两个列表。恕我直言,更短的代码并不意味着更快。
@AhsanulHaque 我在哪里说这是好的解决方案??变得如此令人反感有什么意义?你用 re 完成了你的,但我做了 w/o re,但这仍然是一个解决方案。【参考方案2】:
这个怎么样?
your_string ='ANDREWS VS BALL JA-15-0050 D0015 JUDGE EDWARD A ROBERTS'
print re.sub(r'\s2,','|',your_string.strip())
输出:
ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS
扩展:
我使用了re.sub()
,它接受 3 个参数、一个模式、一个要替换的字符串以及要处理的字符串。
我所做的是将至少两个空格放在一起,我已经用|
替换它们并将其应用于您的字符串。
【讨论】:
【参考方案3】:您可以将正则表达式 '\s2,'
(两个或更多空白字符)应用于每一行,并用单个 '|'
字符替换匹配项。
>>> import re
>>> line = 'ANDREWS VS BALL JA-15-0050 D0015 JUDGE EDWARD A ROBERTS '
>>> re.sub('\s2,', '|', line.strip())
'ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS'
在应用 re.sub
之前从行中去除任何前导和尾随空格可确保您不会在行的开头和结尾获得 '|'
字符。
您的实际代码应该类似于:
import re
with open(filename) as f:
for line in f:
subbed = re.sub('\s2,', '|', line.strip())
# do something here
【讨论】:
谢谢你,真的很好解释。只需要添加一个换行功能。【参考方案4】:s = """B, NICKOLAS CT144531X D1026 JUDGE ANNIE WHITE JOHNSON
ANDREWS VS BALL JA-15-0050 D0015 JUDGE EDWARD A ROBERTS
"""
# Update
re.sub(r"(\S)\ 2,(\S)(\n?)", r"\1|\2\3", s)
In [71]: print re.sub(r"(\S)\ 2,(\S)(\n?)", r"\1|\2\3", s)
B, NICKOLAS|CT144531X|D1026|JUDGE ANNIE WHITE JOHNSON
ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS
【讨论】:
它在末尾附加了一个额外的管道。 完美!干净简单,而且它很好地添加了换行符。【参考方案5】:您的数据看起来像是“文本表格”格式。
我建议使用第一行来确定每列的起点和长度(手动或使用正则表达式编写脚本以确定可能的列),然后编写脚本来迭代文件的行,切片将行分成列段,并将条带应用于每个段。
如果您使用正则表达式,您必须跟踪列数,如果任何给定行的列数超过预期(或与其余列数不同),则会引发错误.如果列的值有两个或多个空格,则在两个或多个空格上拆分会中断,这不仅完全可能,而且很可能。 像这样的文本表不是为了在正则表达式上拆分而设计的,它们是为了在列索引位置上拆分而设计的。
在保存数据方面,您可以使用 csv 模块写入/读取 csv 文件。这将使您比指定分隔符更好地处理引用和转义字符。如果您的某一列有一个 |
字符作为值,除非您使用处理转义或引用文字的策略对数据进行编码,否则您的输出将在读取时中断。
解析上面的文本看起来像这样(我用括号而不是传统格式嵌套了一个列表理解,所以它更容易理解):
cols = ((0,34),
(34, 50),
(50, 59),
(59, None),
)
for line in lines:
cleaned = [i.strip() for i in [line[s:e] for (s, e) in cols]]
print cleaned
然后你可以用类似这样的东西来写它:
import csv
with open('output.csv', 'wb') as csvfile:
spamwriter = csv.writer(csvfile, delimiter='|',
quotechar='"', quoting=csv.QUOTE_MINIMAL)
for line in lines:
spamwriter.writerow([line[col_start:col_end].strip()
for (col_start, col_end) in cols
])
【讨论】:
【参考方案6】:看起来这个库可以很好地解决这个问题: http://docs.astropy.org/en/stable/io/ascii/fixed_width_gallery.html#fixed-width-gallery
令人印象深刻...
【讨论】:
以上是关于使用python从txt中删除空格的主要内容,如果未能解决你的问题,请参考以下文章