将硬编码初始化值转换为CSV

时间:2013-06-26 13:43:47

标签: python parsing csv code-generation

使用Python我想从一堆包含硬编码数据的javascript文件中将下面显示的数据行提取到csv文件中,如下所示:


....html code....

hotels[0] = new hotelData();
hotels[0].hotelName = "MANHATTAN";
hotels[0].hotelPhone = "";
hotels[0].hotelSalesPhone = "";
hotels[0].hotelPhone = 'Phone: 888-350-6432
'; hotels[0].hotelStreet = "787 11TH AVENUE"; hotels[0].hotelCity = "NEW YORK"; hotels[0].hotelState = "NY"; hotels[0].hotelZip = "10019"; hotels[0].hotelId = "51543"; hotels[0].hotelLat = "40.7686";; hotels[0].hotelLong = "-73.992645";; hotels[1] = new hotelData(); hotels[1].hotelName = "KOEPPEL"; hotels[1].hotelPhone = ""; hotels[1].hotelSalesPhone = ""; hotels[1].hotelPhone = 'Phone: 718-721-9100
'; hotels[1].hotelStreet = "57-01 NORTHERN BLVD."; hotels[1].hotelCity = "WOODSIDE"; hotels[1].hotelState = "NY"; hotels[1].hotelZip = "11377"; hotels[1].hotelId = "51582"; hotels[1].hotelLat = "40.75362";; hotels[1].hotelLong = "-73.90366";; var mykey = "AlvQ9gNhp7oNuvjhkalD4OWVs_9LvGHg0ZLG9cWwRdAUbsy-ZIW1N9uVSU0V4X-8"; var map = null; var pins = null; var i = null; var boxes = new Array(); var currentBox = null; var mapOptions = { credentials: mykey, enableSearchLogo: false, showMapTypeSelector: false, enableClickableLogo: false } .....html code .....

因此,所需的csv输出将类似于上述数据的行:

MANHATTAN,,,Phone: 888-350-6432 ...
KOEPPEL,,,Phone: 718-721-9100 ...

我应该使用代码生成工具直接解析上面的语句来获取数据吗?哪种是将数千个Javascript文件中包含的数据转换为csv表格格式的最有效的Python方法?

更新

理想情况下,我希望解决方案将JavaScript语句解析为Python对象,然后将其存储到CSV以最大限度地独立于输入脚本代码的排序和格式化

3 个答案:

答案 0 :(得分:1)

我建议使用正则表达式挑选所有“hotel [#]。...”行,然后将所有结果添加到字典中。然后,使用字典输出到CSV文件。以下应该有效:

import re
import csv


src_text = your_javascript_text
p = re.compile(r'hotels\[(?P<hotelid>\d+)\].(?P<attr>\w+) = ("|\')(?P<attr_val>.*?)("|\');', re.DOTALL)

hotels = {}
fieldnames = []
for result in [m.groupdict() for m in p.finditer(src_text)]:
    if int(result['hotelid']) not in hotels:
        hotels[int(result['hotelid'])] = {}
    if result['attr'] not in fieldnames:
        fieldnames.append(result['attr'])

    hotels[int(result['hotelid'])][result['attr']] = result['attr_val']

output = open('hotels.csv','wb')
csv_writer = csv.DictWriter(output, delimiter=',', fieldnames=fieldnames, quoting=csv.QUOTE_ALL)
csv_writer.writerow(dict((f,f) for f in fieldnames))
for hotel in hotels.items():
    csv_writer.writerow(hotel[1])

你现在有一个带有属性的酒店字典,按照Javascript中的ID分组,以及输出文件“hotels.csv”(带有标题行和正确的转义)。我确实做过像命名小组这样的事情,但实际上并不是必需的,但却发现它更具自我评论性。

应该注意的是,如果在Javascript中提供相同的组两次,比如hotelPhone,则最后一个是唯一存储的。

在处理此类问题时,您和您的判断需要多少耐受性和卫生。您可能需要修改正则表达式以处理示例,而不是提供小样本(即,捕获组中的更改,限制与行开头的匹配等);或转义换行符,如电话号码中的那些;或删除某些文本(例如电话号码中的“电话:”)。我们没有真正的方法来了解这一点,所以请记住这一点。

干杯!

答案 1 :(得分:0)

如果这是你必须经常做的事情,并且你想让这个过程完全自动化,我认为最简单的方法是使用Python解析文件,然后使用csv Python module写入csv。

您的代码可能看起来像这样:

with open("datafile.txt") as f:
    hotel_data = []
    for line in f:
        # Let's make sure the line not empty
        if line:
            if "new hotelData();" in line:
                if hotel_data:
                    write_to_csv(hotel_data)
                    hotel_data = []
        else:
            # Data, still has ending quote and semi colon
            data = line.split("= ")[1]
            # Remove ending quote and semi colon 
            data = data[:-2]
            hotel_data.append(data)

def write_to_csv(hotel_data):
    with open('hotels.csv', 'wb') as csvfile:
        spamwriter = csv.writer(csvfile, delimiter=',',
                                quotechar='""', quoting=csv.QUOTE_MINIMAL)

        spamwriter.writerow(hotel_data)

请注意,我没有测试过此代码,它只是为了帮助您并指出正确的方向,它不是完整的解决方案。

答案 2 :(得分:0)

如果每个酒店都在您的文件中声明了所有字段(即,如果所有酒店都有相同数量的行,即使其中一些是空的),您可以尝试使用简单的正则表达式来提取包围的每个值引号(“xxx”),然后按编号对它们进行分组(例如,将每5个字段分组为一行,然后添加换行符。)

一个可行的简单正则表达式是["'][^"']*["'](编辑:这是因为我看到一些文件(即电话)使用单引号,其余的使用引号)。

要进行搜索,请使用findall

compPattern = re.compile(pattern)
results = compPattern.findall(compPattern)