在Python中使用split()和join()时保留空白符
我有一个数据文件,里面有一些列,像这样:
BBP1 0.000000 -0.150000 2.033000 0.00 -0.150 1.77
而且这些列之间用不同数量的空格分隔。
我的目标是读取这些行,对几行进行一些数学运算,比如把第4列的值乘以0.95,然后把结果写入一个新文件。新文件的格式应该和原来的文件一样,只是我修改过的值会有所不同。
我打算把这些行作为列表中的项来读取。然后我会对我感兴趣的那些行使用 split()
,这样就能得到一个包含各个列值的子列表。接着我进行修改,再用 join()
把这些列连接起来,最后把列表中的行写入一个新的文本文件。
问题是,我有不同数量的空格。我不知道怎么把这些空格以我读取时的方式重新放回去。我能想到的唯一方法是先在分割之前计算行中的字符数,但这会非常麻烦。有没有人有更好的办法来解决这个问题?
3 个回答
4
对于那些开头和/或结尾有空格的行,使用一个更强大的模式 (\S+)
来根据非空格字符进行分割会更好:
import re
line1 = ' 4 426.2 orange\n'
line2 = '12 82.1 apple\n'
re_S = re.compile(r'(\S+)')
items1 = re_S.split(line1)
items2 = re_S.split(line2)
print(items1) # [' ', '4', ' ', '426.2', ' ', 'orange', '\n']
print(items2) # ['', '12', ' ', '82.1', ' ', 'apple', '\n']
这两行在分割后得到的项目数量是一样的,这样很方便。第一项和最后一项总是空格字符串。我们可以用一个空字符串来把这些行重新组合起来:
print(repr(''.join(items1))) # ' 4 426.2 orange\n'
print(repr(''.join(items2))) # '12 82.1 apple\n'
为了和这里其他答案中使用的类似模式 (\s+)
(小写)进行对比,每一行分割后的结果长度和项目位置都不一样:
re_s = re.compile(r'(\s+)')
print(re_s.split(line1)) # ['', ' ', '4', ' ', '20.0', ' ', 'orange', '\n', '']
print(re_s.split(line2)) # ['12', ' ', '82.1', ' ', 'apple', '\n', '']
如你所见,这样处理起来会稍微复杂一些,难以保持一致。
9
还有一种方法可以做到这一点:
s = 'BBP1 0.000000 -0.150000 2.033000 0.00 -0.150 1.77'
s.split(' ')
>>> ['BBP1', '', '', '0.000000', '', '-0.150000', '', '', '', '2.033000', '', '0.00', '-0.150', '', '', '1.77']
如果我们在分割函数中指定空格作为参数,它会创建一个列表,而不会把连续的空格都去掉。所以,在使用'连接'函数之后,原来的空格数量会被恢复。
45
在这种情况下,你可以使用 re.split()
,并且要用到一个分组:
re.split(r'(\s+)', line)
这样做会同时返回列和空格,这样你就可以在后面把这一行重新组合起来,保持原来的空格数量。
举个例子:
>>> re.split(r'(\s+)', line)
['BBP1', ' ', '0.000000', ' ', '-0.150000', ' ', '2.033000', ' ', '0.00', ' ', '-0.150', ' ', '1.77']
你可能确实想把最后的换行符去掉。