python - 在 Python 中读取分布在多个输入行的记录

标签 python parsing csv readline formatter

我有一个高度非结构化的文本数据文件,其中的记录通常跨越多个输入行。

  • 与普通文本一样,每条记录都有由空格分隔的字段,因此每个字段都必须通过附加信息而不是“csv 字段分隔符”来识别。
  • 许多不同的记录也共享前两个字段,它们是:
    • 月份的天数(1 到 31);
    • 本月的前三个字母。
  • 但我知道这个带有日期字段和月份前缀字段的“特殊”记录后跟与相同“时间戳”(日/月)相关的记录 ),不包含该信息
  • 我确信第三个字段与许多单词的非结构化句子相关,例如“由于这个原因在那个地方使用此工具执行的操作”
  • 我知道每条记录都可以有一个或两个数字字段作为最后一个字段。
  • 我还知道每条新记录都以新行开头(当天/月份的第一条记录以及同一天/月份的后续记录)。

因此,总而言之,每条记录都应转换为类似于以下结构的 CSV 记录: DD,MM,非结构化文本 bla bla bla,number1,number2

数据示例如下:

> 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()

最佳答案

您可以使用类似的方法来重新格式化输入文本。代码很可能会根据输入中允许的内容进行一些清理。

list = file_in.readlines()
list2 = []     
string =""
i = 0

while i < len(list):
   ## remove any leading or trailing white space then split on ' '
   line_arr = list[i].lstrip().rstrip().split(' ')

您可能需要更改这部分,因为这里我假设一条记录必须至少以一个数字结尾。也有些人不赞成这样使用 try/except 。 (此部分来自How do I check if a string is a number (float) in Python?)

   ##check for float at end of line
   try:
      float(line_arr[-1])
   except ValueError:
      ##not a float 
      ##remove new line and add to previous line
      string = string.replace('\n',' ') +  list[i]
   else:
      ##there is a float at the end of current line
      ##add to previous then add record to list2
      string = string.replace('\n',' ') +  list[i]
      list2.append(string)
      string = ""
   i+=1

添加到代码中的输出是:

20/09/2011||line_number_1
Text unstructured of the second record bla bla 406.25 10001||line_number_2
06/10/2011||line_number_3
28/11/2011||line_number_4
Second record of the day/month BUT the fifth record of the file 500 90.25||line_number_5

我认为这很接近您正在寻找的内容。

关于python - 在 Python 中读取分布在多个输入行的记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9673703/

相关文章:

python - 递归解析而不是使用 pop

javascript - javascript如何从url解析xml获取属性

java - 无法让我的程序接受多个整数

python - 怎么把500Hz csv数据文件转换成wav音频文件?

python - 在 python + beautiful soup 上使用正则表达式

python - 如何在 Python 中运行脚本时操作图形?

python - Postgresql 启动失败

python - 用 Python Pandas 写入 to_csv : Choose which column index to insert new data

php - 通过php将csv从mysql保存到服务器

matlab - 如果 csvread 失败则跳过文件 Matlab