我有一个高度非结构化的文本数据文件,其记录通常跨越多个输入行。阅读记录分布在Python中的多个输入行中
- 每条记录的领域用空格隔开,作为普通的文本,所以每场必须通过额外的信息,而不是“CSV字段分隔符”被识别。
- 许多不同的记录还共享前两个字段它们是:
- 的月日(1到31)的数目;
- 本月的前三个字母。
- 但我知道,有一天的日场和月前缀场这个“特殊”的记录,然后与同一“时间戳”记载(日/月)是不包含该信息。
- 我知道肯定第三场与非结构化句子像
- 我知道,每一个记录可以有“用这个工具对地方为此进行操作”很多的话一个或两个数字作为最后一个字段的字段为。
- 我也知道每个新记录都以新行(这是日/月的第一条记录以及同一天/月的以下记录)开头。
因此,要总结,每个记录应转化为CSV记录类似这样的结构: DD,MM,非结构化文本唧唧歪歪,数字1,数字
的数据的一个例子是以下:
> 20 Sep This is the first record, bla bla bla 10.45
> Text unstructured
> of the second record bla bla
> 406.25 10001
> 6 Oct Text of the third record thatspans on many
> lines bla bla bla 60
> 28 Nov Fourth
> record
> 27.43
> Second record of the
> day/month BUT the fifth record of the file 500 90.25
我公司开发在Python以下解析器,但我无法弄清楚如何读取输入文件的多行从逻辑上把它们作为一个独特的资料片。我想我应该在另一个内部使用两个循环,但我无法处理循环索引。
非常感谢您的帮助!
# I need to deal with is_int() and is_float() functions to handle records with 2 numbers
# that must be separated by a csv_separator in the output record...
import sys
days_in_month = range(1,31)
months_in_year = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
csv_separator = '|'
def is_month(s):
if s in months_in_year:
return True
else:
return False
def is_day_in_month(n_int):
try:
if int(n_int) in days_in_month:
return True
else:
return False
except ValueError:
return False
#file_in = open('test1.txt','r')
file_in = open(sys.argv[1],'r')
#file_out = open("out_test1.txt", "w") # Use "a" instead of "w" to append to file
file_out = open(sys.argv[2], "w") # Use "a" instead of "w" to append to file
counter = 0
for line in file_in:
counter = counter + 1
line_arr = line.split()
date_str = ''
if is_day_in_month(line_arr[0]):
if len(line_arr) > 1 and is_month(line_arr[1]):
# Date!
num_month = months_in_year.index(line_arr[1]) + 1
date_str = '%02d' % int(line_arr[0]) + '/' + '%02d' % num_month + '/' + '2011' + csv_separator
elif len(line_arr) > 1:
# No date, but first number less than 31 (number of days in a month)
date_str = ' '.join(line_arr) + csv_separator
else:
# No date, and there is only a number less than 31 (number of days in a month)
date_str = line_arr[0] + csv_separator
else:
# there is not a date (a generic string, or a number higher than 31)
date_str = ' '.join(line_arr) + csv_separator
print >> file_out, date_str + csv_separator + 'line_number_' + str(counter)
file_in.close()
file_out.close()
您还可能有所帮助:http://stackoverflow.com/questions/42950/get-last-day-of-the-month-in-python – 2012-03-12 19:53:32
所以每一行是一个记录,是否正确?你能否依靠日志的文本块中没有数字字符? – 2012-03-12 19:58:43
你应该看看pyparsing(http://pyparsing.wikispaces.com/)模块。 – Hooked 2012-03-12 20:46:01