#python #parsing
#python #синтаксический анализ
Вопрос:
Я полный новичок в Python. Я сталкиваюсь с текстовыми файлами, которые мне нужно отформатировать. Мне в основном нужно взять данные поля, которые начинаются с определенного символа, и вывести данные поля в новый файл, в котором все поля будут разделены выбранным мной символом.
Вот краткий пример.
; Record 1
@FULLTEXT PAGE
@T R000358
@C ENDDOC# R000358
@C BEGATTACH R000358
@C ENDATTACH R000358
@C MAILSTORE No
@C AUTHOR
@C BCC
@C CC
@C COMMENTS
@C ATTACH
@C DATECREATED 11/23/2010
@C DATELASTMOD 07/18/2010
@C DATELASTPRNT
@C DATERCVD
@C DATESENT
@C FILENAME wrangling.wpd
@C LASTAUTHOR
@C ORGANIZATION
@C REVISION
@C SUBJECT
@C TIMEACCESSED 00:00:00
@C TIMECREATED 15:21:34
@C TIMELASTMOD 09:04:12
@C TIMELASTPRNT
@C TIMERCVD
@C TIMESENT
@C TITLE
@C TO
@C FROM
Для каждой «записи» «@C» и «@T» — это разделитель полей, за которым следует пробел, затем имя поля, за которым следует пробел, затем данные поля. Мне нужно, чтобы все данные поля были разделены одной строкой, а не столбцом, как показано выше.
Я хочу вывести в новый файл каждую запись примерно так.
«R000358», «R000358», «R000358», «R000358», «Нет» и т. Д. И т. Д. (в одной строке)
Этот пример разделен запятыми, но он может измениться, но я решил, что начну с этого.
Любая помощь будет оценена. Заранее спасибо.
Комментарии:
1. Что такое разделитель записей?
Ответ №1:
Неясно, как разделяются записи и что именно вы хотели бы сделать со своим выводом, но вот простой анализатор, который должен помочь вам начать:
s = '''
; Record 1
@FULLTEXT PAGE
@T R000358
@C ENDDOC# R000358
@C BEGATTACH R000358
@C ENDATTACH R000358
@C MAILSTORE No
@C AUTHOR
@C BCC
@C CC
@C COMMENTS
@C ATTACH
@C DATECREATED 11/23/2010
@C DATELASTMOD 07/18/2010
@C DATELASTPRNT
@C DATERCVD
@C DATESENT
@C FILENAME wrangling.wpd
@C LASTAUTHOR
@C ORGANIZATION
@C REVISION
@C SUBJECT
@C TIMEACCESSED 00:00:00
@C TIMECREATED 15:21:34
@C TIMELASTMOD 09:04:12
@C TIMELASTPRNT
@C TIMERCVD
@C TIMESENT
@C TITLE
@C TO
@C FROM
'''.splitlines()
records = []
record = {}
for line in s:
if line.startswith('; Record'):
record = {}
records.append(record)
elif line.startswith(('@T ', '@C ')):
f = line.split()
fieldname = f[1]
i = line.find(fieldname) len(fieldname)
fieldvalue = line[i:].lstrip()
record[fieldname] = fieldvalue
import pprint
pprint.pprint(records)
Удачи с Python.
Ответ №2:
def getRecordRows( file, start_characters, delimiter):
returnRows = []
for line in open(file):
if line.startswith(start_characters):
returnRows.append( line[len(start_characters):] )
return delimiter.join( returnRows )
Пример использования:
file = /path/to/file
getRecordRows(file, '@T', ',')
Ответ №3:
Начните с открытия файла:
with open('inputfile','r') as fil:
# file read-in stuff here
Используйте with
идиому, если вы используете python 2.5 и выше, в противном случае выполните:
try:
fil = open('inputfile','r')
# file read-in stuff here
finally:
fil.close()
Чтобы преобразовать содержимое файла в строки, проверьте file.readline()
(читает по одной строке за раз; использовать для больших файлов) и file.readlines()
(считывает весь файл в список, по одной строке на запись) здесь .
Чтобы записать файл, используйте приведенную выше логику для чтения, за исключением открытия файла в режиме записи, например: open('outputfile','w')
Чтобы обработать форматирование для вашего выходного файла, посмотрите на строковые методы здесь. В частности, взгляните на str.split()
и str.join()
, которые позволяют легко разбивать строки на списки и объединять элементы списка в строки с помощью разделителя.
Ответ №4:
record = None
records = []
with open('records.dat') as stream:
for line in stream:
item = line.strip().split()
if not item:
continue
if item[0] == ';':
record = []
records.append((item[-1], record))
elif record is not None:
if item[0] == '@C' and len(item) <= 2:
record.append('')
elif item[0] in ('@T', '@C'):
record.append(item[-1])
for identifier, record in records:
print '[%s]: %s' % (identifier, ', '.join(record))