我有一堆带有表格数据的文本文件。它看起来像这样:
1. BRISTOL CITY 42 16 4 1 43 13 8 7 6 23 27 59
2. Plymouth Argyle 42 18 3 0 47 6 5 4 12 14 23 53
3. Swansea City 42 13 6 2 46 14 9 3 9 32 31 53
4. Brighton & Hove Albion 42 15 3 3 39 13 5 8 8 13 21 51
5. Luton Town 42 14 4 3 47 18 7 3 11 21 31 49
6. Millwall 42 9 10 2 27 13 5 8 8 18 27 46
7. Portsmouth 42 10 5 6 34 20 9 3 9 24 32 46
8. Northampton 42 13 6 2 40 17 4 5 12 14 27 45
9. Swindon Town 42 14 4 3 41 17 3 7 11 21 39 45
10. Watford 42 10 6 5 35 23 7 4 10 22 31 44
11. Queen's Park Rangers 42 10 4 7 34 24 6 6 9 20 25 42
12. Charlton Athletic 42 11 6 4 33 14 3 8 10 22 37 42
13. Bristol Rovers 42 7 9 5 25 19 6 7 8 10 17 42
14. Brentford 42 9 4 8 27 23 4 8 9 14 28 38
15. Southend United 42 10 6 5 35 18 2 7 12 14 36 37
16. Gillingham 42 13 4 4 38 18 2 3 16 13 41 37
17. Merthyr Town 42 10 4 7 27 17 1 10 10 12 31 36
18. Norwich City 42 8 7 6 29 26 5 3 13 22 45 36
19. Reading 42 9 8 4 24 15 1 6 14 12 40 34
20. Exeter City 42 10 4 7 27 18 3 3 15 20 66 33
这是非常规则的,但是没有标准的分隔符,并且列宽不是表到表的标准(即使在相同的文件中)。 (仅空格不是足够的分隔符,因为许多名称包含空格,在某些地方,列仅由一个空格分隔。)
我想将它解析为Python对象,但目前还不清楚最好的方法是什么。有没有办法使用CSV模块解析它?我需要使用正则表达式吗?有人写了一个很棒的python库来解析表格文本文件吗?
答案 0 :(得分:1)
制作正则表达式。 Look it up here for explanation/modifying.
使用[\D]+?
提取行的名称(如Accrington)。这意味着“尽可能多地使用非数字来填充线条”。 (+?
- 非贪心)所以你可以得到字母和(最小)空格,这就是你的行的名字......
import re
pattern = re.compile(r"^(\d+.)\s*([\D]+?)" + r"\s+(\d+)"*12 + r"\s*$")
<强>测试强>
match = pattern.match("7. Accrington 22 5 3 3 26 17 1 5 5 22 31 20")
print match.groups()
Out[133]:
('7.',
'Accrington',
'22',
'5',
'3',
'3',
'26',
'17',
'1',
'5',
'5',
'22',
'31',
'20')
match2 = pattern.match("91. Accrington Bay 22 5 3 3 26 17 1 5 5 22 31 20")
print match2
Out[134]:
('91.',
'Accrington Bay',
'22',
'5',
'3',
'3',
'26',
'17',
'1',
'5',
'5',
'22',
'31',
'20')
答案 1 :(得分:0)
最简单的解决方案是使用正则表达式。
您可以使用split()
方法(Python包含的re
模块除外)在每个连续空格序列中拆分数据。
import re
data = '7. Accrington 22 5 3 3 26 17 1 5 5 22 31 20'
for line in re.split('\n+', data):
print(re.split('\s+', line))
将打印以下内容:
['7.', 'Accrington', '22', '5', '3', '3', '26', '17', '1', '5', '5', '22', '31', '20']
请注意,上面的示例还处理多行数据(假设这些行由连续的换行符分隔)。
答案 2 :(得分:0)
skipinitialspace
是您使用csv
模块所需的内容。
$ cat << EOF > /tmp/sample.csv
> 7. Accrington 22 5 3 3 26 17 1 5 5 22 31 20
> 7. Accrington 22 5 3 3 26 17 1 5 5 22 31 20
> 8. Accrington 22 5 3 3 26 17 1 5 5 22 31 22
> 7. Accrington 22 5 3 3 26 17 1 5 5 22 31 21
> EOF
$ python
Python 2.7.5 (default, Aug 25 2013, 00:04:04)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import csv
>>> reader = csv.reader(open('/tmp/sample.csv'), skipinitialspace=True, quoting=csv.QUOTE_NONE, delimiter=' ')
>>> for row in reader:
... print row
...
['7.', 'Accrington', '22', '5', '3', '3', '26', '17', '1', '5', '5', '22', '31', '20']
['7.', 'Accrington', '22', '5', '3', '3', '26', '17', '1', '5', '5', '22', '31', '20']
['8.', 'Accrington', '22', '5', '3', '3', '26', '17', '1', '5', '5', '22', '31', '22']
['7.', 'Accrington', '22', '5', '3', '3', '26', '17', '1', '5', '5', '22', '31', '21']
不要忘记你可以解压缩每行的结果,如下所示:
>>> for pk, name, a, b, c, d, e, f, g, h, i, j, k, l in reader: