Вот начало в Python.Нечто подобное может быть сделано в Perl.
col_start_pat = re.compile( r'\s+\s(?=\S)' )
for row in ( r.rstrip() for r in data.splitlines() ):
if not row: continue
def matches( row ):
offset= 0
for m in col_start_pat.finditer( row ):
yield offset, row[offset:m.end(0)].rstrip()
offset= m.end(0)
yield offset, row[offset:].rstrip()
columns= list( matches( row ) )
if not columns: continue
print( columns )
Это не делает всю работу.Он просто идентифицирует «поля» в каждой строке как последовательность кортежей, которые выглядят следующим образом.
[(0, 'DOE JANE H'), (50, 'STATE'), (64, '1994'), (73, '0002'), (84, 'SAVINGS'), (98, '52'), (112, '33.99'), (120, '0')]
[(0, ''), (50, 'EMPLOYEES'), (84, 'ACCOUNTS')]
[(0, ''), (50, 'CREDIT UNION')]
[(0, ''), (17, 'SOMECITY'), (31, 'ZZ'), (39, '12345')]
[(0, 'DOE JANE H'), (16, 'OR SOME OTHER OWNER'), (46, 'STATE'), (60, '1994'), (69, '0002'), (80, 'SAVINGS'), (94, '52'), (108, '33.99'), (116, '0')]
[(0, ''), (46, 'EMPLOYEES'), (80, 'ACCOUNTS')]
[(0, ''), (46, 'CREDIT UNION')]
[(0, ''), (16, 'SOMECITY'), (30, 'ZZ'), (38, '12345')]
[(0, 'DOE'), (41, 'STATE'), (55, '1994'), (64, '0002'), (75, 'SAVINGS'), (89, '52'), (103, '33.99'), (111, '0')]
[(0, 'JANE'), (41, 'EMPLOYEES'), (75, 'ACCOUNTS')]
[(0, 'H'), (41, 'CREDIT UNION')]
[(0, ''), (12, 'SOMECITY'), (26, 'ZZ'), (34, '12345')]
Следующая часть заключается в использовании номеров столбцов заголовка для идентификации формата, а затем сворачивания строк водин объект.
Расширение на это ...
pat1= [0, 50, 64, 73, 84, 98, 112, 120]
pat2= [0, 16, 46, 60, 69, 80, 94, 108, 116]
pat3= [0, 41, 55, 64, 75, 89, 103, 111]
def columns( data ):
col_start_pat = re.compile( r'\s+\s(?=\S)' )
for row in ( r.rstrip() for r in data.splitlines() ):
if not row: continue
def matches( row ):
offset= 0
for m in col_start_pat.finditer( row ):
yield offset, row[offset:m.end(0)].rstrip()
offset= m.end(0)
yield offset, row[offset:].rstrip()
columns= list( matches( row ) )
yield columns
def row_groups( data ):
columns_iter= columns(data)
record= []
for parsed in columns_iter:
offsets= [ c[0] for c in parsed ]
if offsets == pat1:
if record: yield( format, record )
format= 1
record= []
elif offsets == pat2:
if record: yield( format, record )
format= 2
record= []
elif offsets == pat3:
if record: yield( format, record )
format= 3
record= []
record.extend( parsed )
yield( format, record )
for record in row_groups( data ):
print( record )
Получает вам следующее:
(1, [(0, 'DOE JANE H'), (50, 'STATE'), (64, '1994'), (73, '0002'), (84, 'SAVINGS'), (98, '52'), (112, '33.99'), (120, '0'), (0, ''), (50, 'EMPLOYEES'), (84, 'ACCOUNTS'), (0, ''), (50, 'CREDIT UNION'), (0, ''), (17, 'SOMECITY'), (31, 'ZZ'), (39, '12345')])
(2, [(0, 'DOE JANE H'), (16, 'OR SOME OTHER OWNER'), (46, 'STATE'), (60, '1994'), (69, '0002'), (80, 'SAVINGS'), (94, '52'), (108, '33.99'), (116, '0'), (0, ''), (46, 'EMPLOYEES'), (80, 'ACCOUNTS'), (0, ''), (46, 'CREDIT UNION'), (0, ''), (16, 'SOMECITY'), (30, 'ZZ'), (38, '12345')])
(3, [(0, 'DOE'), (41, 'STATE'), (55, '1994'), (64, '0002'), (75, 'SAVINGS'), (89, '52'), (103, '33.99'), (111, '0'), (0, 'JANE'), (41, 'EMPLOYEES'), (75, 'ACCOUNTS'), (0, 'H'), (41, 'CREDIT UNION'), (0, ''), (12, 'SOMECITY'), (26, 'ZZ'), (34, '12345')])
Который содержит всю информацию;для этого нужна просто умная сборка.