用python从txt中删除空格

时间:2016-04-30 17:20:32

标签: python regex python-2.7 whitespace shlex

我有一个.txt文件(从网站上格式化为预先格式化的文本),其中的数据如下所示:

B, NICKOLAS                       CT144531X       D1026    JUDGE ANNIE WHITE JOHNSON  
ANDREWS VS BALL                   JA-15-0050      D0015    JUDGE EDWARD A ROBERTS        

我想删除列之间的所有额外空格(它们实际上是不同数量的空格,而不是制表符)。我还想用一些分隔符替换它(tab或pipe,因为数据中有逗号),如下所示:

ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS

环顾四周,发现最好的选择是使用正则表达式或shlex来分割。两个类似的场景:

6 个答案:

答案 0 :(得分:7)

您可以将正则表达式'\s{2,}'(两个或多个空白字符)应用于每一行,并将匹配项替换为单个'|'字符。

>>> import re
>>> line = 'ANDREWS VS BALL                   JA-15-0050      D0015    JUDGE EDWARD A ROBERTS        '
>>> re.sub('\s{2,}', '|', 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('\s{2,}', '|', line.strip())
        # do something here

答案 1 :(得分:6)

这个怎么样?

your_string ='ANDREWS VS BALL                   JA-15-0050      D0015    JUDGE EDWARD A ROBERTS'
print re.sub(r'\s{2,}','|',your_string.strip())

输出:

ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS

Expanation:

我使用了re.sub(),其中包含3个参数,一个模式,一个要替换的字符串以及您想要处理的字符串。

我所做的是至少占用两个空格,我已用|替换它们并将其应用到你的字符串上。

答案 2 :(得分:5)

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

答案 3 :(得分:3)

考虑到分隔列至少有两个空格,您可以使用:

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

答案 4 :(得分:3)

看起来您的数据位于" text-table"格式。

我建议使用第一行来计算每列的起点和长度(手动或用正则表达式编写脚本以确定可能的列),然后编写脚本来迭代文件的行,切片将行放入列段,并将条带应用于每个段。

如果使用正则表达式,则必须跟踪列数并在任何给定行超过预期列数(或与其余列数不同)时引发错误。如果列的值具有两个或更多空格,则拆分两个或多个空格将会中断,这不仅是完全可能的,而且也可能。 像这样的文字表并不是设计为在正则表达式上拆分,而是设计为在列索引位置上拆分。

在保存数据方面,您可以使用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
                             ])

答案 5 :(得分:0)

看起来这个库可以很好地解决这个问题: http://docs.astropy.org/en/stable/io/ascii/fixed_width_gallery.html#fixed-width-gallery

印象深刻...