使用 python 从 txt 中删除白色 space
Removing white space from txt with python
我有一个 .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
环顾四周,发现最好的选择是使用正则表达式或 shlex 进行拆分。两个相似的场景:
- Python Regular expression must strip whitespace except between quotes,
- Remove white spaces from dict : Python.
考虑到至少有两个空格分隔列,您可以使用:
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
这个呢?
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
解释:
我使用了 re.sub()
,它有 3 个参数、一个模式、一个要替换的字符串和要处理的字符串。
我所做的是将至少两个 space 放在一起,我将它们替换为 |
并将其应用于您的字符串。
您可以将正则表达式 '\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
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"|", s)
In [71]: print re.sub(r"(\S)\ {2,}(\S)(\n?)", r"|", s)
B, NICKOLAS|CT144531X|D1026|JUDGE ANNIE WHITE JOHNSON
ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS
您的数据似乎是 "text-table" 格式。
我建议使用第一行来确定每列的起点和长度(手动或使用正则表达式编写脚本来确定可能的列),然后编写脚本来迭代文件的行, 将行分割成列段,并将 strip 应用于每个段。
如果您使用正则表达式,您必须跟踪列数并在任何给定行的列数超过预期(或不同的列数)时引发错误比其他人多)。如果列的值有两个或更多个空格,则拆分两个或更多个空格将会中断,这不仅完全可能,而且很有可能。 像这样的文本表并非设计为按正则表达式拆分,而是设计为按列索引位置拆分。
在保存数据方面,可以使用csv模块write/read转换成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
])
看起来这个库可以很好地解决这个问题:
http://docs.astropy.org/en/stable/io/ascii/fixed_width_gallery.html#fixed-width-gallery
印象深刻...
我有一个 .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
环顾四周,发现最好的选择是使用正则表达式或 shlex 进行拆分。两个相似的场景:
- Python Regular expression must strip whitespace except between quotes,
- Remove white spaces from dict : Python.
考虑到至少有两个空格分隔列,您可以使用:
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
这个呢?
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
解释:
我使用了 re.sub()
,它有 3 个参数、一个模式、一个要替换的字符串和要处理的字符串。
我所做的是将至少两个 space 放在一起,我将它们替换为 |
并将其应用于您的字符串。
您可以将正则表达式 '\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
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"|", s)
In [71]: print re.sub(r"(\S)\ {2,}(\S)(\n?)", r"|", s)
B, NICKOLAS|CT144531X|D1026|JUDGE ANNIE WHITE JOHNSON
ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS
您的数据似乎是 "text-table" 格式。
我建议使用第一行来确定每列的起点和长度(手动或使用正则表达式编写脚本来确定可能的列),然后编写脚本来迭代文件的行, 将行分割成列段,并将 strip 应用于每个段。
如果您使用正则表达式,您必须跟踪列数并在任何给定行的列数超过预期(或不同的列数)时引发错误比其他人多)。如果列的值有两个或更多个空格,则拆分两个或更多个空格将会中断,这不仅完全可能,而且很有可能。 像这样的文本表并非设计为按正则表达式拆分,而是设计为按列索引位置拆分。
在保存数据方面,可以使用csv模块write/read转换成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
])
看起来这个库可以很好地解决这个问题: http://docs.astropy.org/en/stable/io/ascii/fixed_width_gallery.html#fixed-width-gallery
印象深刻...