1

我有一个插入符号分隔的文件。文件中唯一的插入符号是分隔符——文本中没有。其中一些字段是自由文本字段并包含嵌入的换行符。这使得解析文件非常困难。我需要记录末尾的换行符,但我需要将它们从带有文本的字段中删除。

这是来自全球综合航运信息系统的开源海盗数据。这是三个记录,前面是标题行。第一个船名是 NORMANNIA,第二个是“Unkown”,第三个是 KOTA BINTANG。

船名^船旗^吨位^日期^时间^imo_num^ship_type^ship_released_on^time_zone^incident_position^coastal_state^area^lat^lon^incident_details^crew_ship_cargo_conseq^incident_location^ship_status_when_attacked^num_involved_in_attack^crew_conseq_^weapons_used_by_attackers^ship_partscrew_raid船员_人质_绑架^袭击^赎金^船长_船员行动_采取^reported_to_coastal_authority^reported_to_which_coastal_authority^reporting_state^reporting_intl_org^coastal_state_action_taken
NORMANNIA^Liberia^24987^2009-09-19^22:30^9142980^散货船^^^Off Pulau Mangkai,^^South China Sea^3° 04.00' N^105° 16.00' E^八名海盗手持长刀子和撬棍登上了正在航行的船。他们闯入 2/O 舱,绑住他的手,用长刀威胁他的喉咙。海盗强迫 2/O 召唤法师。海盗们在主人家门口等着的时候,抓住了C/E,绑住了他的手。船长的船舱一打开,海盗们就冲进了船舱。他们用长刀和撬棍威胁他并要钱。主人的双手被绑起来,他们强迫他到船尾站。海盗们带着船上的现金和船员的个人物品跳进一艘长长的木船上逃走了。C/E和2/O设法挣脱并发出警报^海贼们绑住了Master的手,C/E 和 2/O。海盗偷走了船上的现金和船长的现金、C/E 和 2/O 现金和个人物品^在国际水域^汽船^5-10人^对船员的暴力威胁^刀^^^^^^^SSAS激活并报告给业主^^利比里亚当局^^ICC-IMB 海盗报告中心吉隆坡^-
未知^马绍尔群岛^19846^2013-08-28^23:30^^杂货船^^^Cam Pha港^越南^南海^20° 59.92' N^107° 19.00' E^停泊时,六名劫匪通过锚链登上了船只,并切断了通往艏楼商店门的挂锁。他们拆除了艏楼商店绳索舱口的螺丝扣和绑扎。劫匪在值班值班人员交接时被二副看到时听到警报后逃跑。被切开。

两个中心卸扣和一个末端卸扣被盗“^在港口区域^在锚点^5-10人^^无/未说明^主甲板^^^^^^-^^^越南^”ReCAAP ISC via ReCAAP联络点(越南)

ReCAAP ISC 通过 Focal Point(新加坡)"^-
KOTA BINTANG^Singapore^8441^2002-05-12^15:55^8021311^散货船^^UTC^^^南海^^^七名手持长刀的劫匪在航行中登上了这艘船。他们打破了舱门,劫持了一名船员并强迫船长打开舱门。然后他们将船长和船员绑起来,强迫他们回到船尾甲板上,劫匪从那里跳下船,乘一艘没有照明的船逃跑^船长和学员袭击;现金、船员财物和船上现金被盗^在领海内^汽运^5-10人^对船员的实际暴力^刀^^^^^^2^^-^^是的。特区、雅加达和印度尼西亚海军总部通知^^ICC-IMB PRC Kuala Lumpur^-

您会注意到第一条和第三条记录很好且易于解析。第二条记录“Unkown”有一些嵌套的换行符。

我应该如何在 python 脚本中删除嵌套的换行符(但不是记录末尾的那些)(或者,如果有更简单的方法),以便我可以将这些数据导入 SAS?

4

3 回答 3

2

将数据加载到字符串中然后执行

import re
newa=re.sub('\n','',a)

newa 中不会有换行符

newa=re.sub('\n(?!$)','',a)

它把那些留在了行尾,但去掉了其余的

于 2013-10-25T19:09:47.213 回答
2

我看到您已将其标记为正则表达式,但我建议使用内置 CSV 库来解析它。CSV 库将正确解析文件,将换行符保留在应有的位置。

Python CSV 示例:http ://docs.python.org/2/library/csv.html

于 2013-10-25T23:12:29.977 回答
1

I solved the problem by counting the number of delimiters encountered and manually switching to a new record when I reached the number associated with a single record. I then stripped all of the newline characters and wrote the data back out to a new file. In essence, it's the original file with the newline characters stripped from the fields but with a newline character at the end of each record. Here's the code:

f = open("events.csv", "r")

carets_per_record = 33

final_file = []
temp_file  = []
temp_str   = ''
temp_cnt   = 0

building   = False

for i, line in enumerate(f):

    # If there are no carets on the line, we are building a string
    if line.count('^') == 0:
        building = True

    # If we are not building a string, then set temp_str equal to the line
    if building is False:
        temp_str = line
    else:
        temp_str = temp_str + " " + line

    # Count the number of carets on the line
    temp_cnt = temp_str.count('^')

    # If we do not have the proper number of carets, then we are building
    if temp_cnt < carets_per_record:
        building = True

    # If we do have the proper number of carets, then we are finished
    # and we can push this line to the list
    elif temp_cnt == carets_per_record:
        building = False
        temp_file.append(temp_str)

# Strip embedded newline characters from the temp file
for i, item in enumerate(temp_file):
    final_file.append(temp_file[i].replace('\n', ''))

# Write the final_file list out to a csv final_file
g = open("new_events.csv", "wb")


# Write the lines back to the file
for item in enumerate(final_file):
    # item is a tuple, so we get the content part and append a new line
     g.write(item[1] + '\n')

# Close the files we were working with
f.close()
g.close()
于 2013-11-01T13:29:35.790 回答