2

我有大量这种类型的数据:

  array(14) {
    ["ap_id"]=>
    string(5) "22755"
    ["user_id"]=>
    string(4) "8872"
    ["exam_type"]=>
    string(32) "PV Technical Sales Certification"
    ["cert_no"]=>
    string(12) "PVTS081112-2"
    ["explevel"]=>
    string(1) "0"
    ["public_state"]=>
    string(2) "NY"
    ["public_zip"]=>
    string(5) "11790"
    ["email"]=>
    string(19) "ivorabey@zeroeh.com"
    ["full_name"]=>
    string(15) "Ivor Abeysekera"
    ["org_name"]=>
    string(21) "Zero Energy Homes LLC"
    ["org_website"]=>
    string(14) "www.zeroeh.com"
    ["city"]=>
    string(11) "Stony Brook"
    ["state"]=>
    string(2) "NY"
    ["zip"]=>
    string(5) "11790"
  }

我在 python 中编写了一个 for 循环,它读取文件,为每个数组创建一个字典并存储如下元素:

a = 0
data = [{}]

with open( "mess.txt" ) as messy:
        lines = messy.readlines()
        for i in range( 1, len(lines) ):
            line = lines[i]
            if "public_state" in line:
                data[a]['state'] = lines[i + 1]
            elif "public_zip" in line:
                data[a]['zip'] = lines[i + 1]
            elif "email" in line:
                data[a]['email'] = lines[i + 1]
            elif "full_name" in line:
                data[a]['contact'] = lines[i + 1]
            elif "org_name" in line:
                data[a]['name'] = lines[i + 1]
            elif "org_website" in line:
                data[a]['website'] = lines[i + 1]
            elif "city" in line:
                data[a]['city'] = lines[i + 1]
            elif "}" in line:
                a += 1
                data.append({})

我知道我的代码很糟糕,但我对 Python 还是很陌生。如您所见,我的大部分项目已经完成。剩下的就是从实际数据中去除代码标签。例如,我需要string(15) "Ivor Abeysekera"成为Ivor Abeysekera".

经过一番研究,我考虑.lstrip()了,但由于前面的文字总是不同的......我被卡住了。

有没有人有解决这个问题的聪明方法?干杯!

编辑:我在 Windows 7 上使用 Python 2.7。

4

4 回答 4

2

错误的解决方案基于当前问题

但要回答你的问题,只需使用

info_string = lines[i + 1]
value_str = info_string.split(" ",1)[-1].strip(" \"")

更好的解决方案

您是否有权访问生成该文件的 php.... 如果您只是这样做echo json_encode($data);而不是使用var_dump

相反,如果你让他们输出 json 它(json 输出)看起来像

{"variable":"value","variable2","value2"}

然后你可以像这样阅读它

import json
json_str = requests.get("http://url.com/json_dump").text  # or however you get the original text
data = json.loads(json_str)
print data
于 2013-08-22T18:25:36.830 回答
2

根据代码标签的格式,您可以拆分该行,"然后选择第二个元素。

s = 'string(15) "Ivor Abeysekera"'
temp = s.split('"')[1]
# temp is 'Ivor Abeysekera'

请注意,这将摆脱尾随",如果您需要它,您可以随时将其重新添加。在您的示例中,这看起来像:

data[a]['state'] = lines[i + 1].split('"')[1]
# etc. for each call of lines[i + 1]

因为你调用它太多(不管你使用什么答案)你应该把它变成一个函数:

def prepare_data(line_to_fix):
    return line_to_fix.split('"')[1]
# latter on...
data[a]['state'] = prepare_data(lines[i + 1])

这会给你更多的灵活性。

于 2013-08-22T18:25:43.693 回答
1

您应该为此使用正则表达式(正则表达式): http ://docs.python.org/2/library/re.html

使用以下代码可以轻松完成您打算做的事情:

# Import the library
import re

# This is a string just to demonstrate
a = 'string(32) "PV Technical Sales Certification"'

# Create the regex
p = re.compile('[^"]+"(.*)"$')

# Find a match
m = p.match(a)

# Your result will be now in s
s = m.group(1)

希望这可以帮助!

于 2013-08-22T18:35:41.743 回答
0

您可以通过遍历所有行并跟踪您在块中的位置来有状态地执行此操作:

# Make field names to dict keys
fields = {
    'public_state': 'state',
    'public_zip': 'zip',
    'email': 'email',
    'full_name': 'contact',
    'org_name': 'name',
    'org_website': 'website',
    'city': 'city',
}

data = []
current = {}
key = None
with open( "mess.txt" ) as messy:
    for line in messy.split('\n'):
        line = line.lstrip()
        if line.startswith('}'):
            data.append(current)
            current = {}
        elif line.startswith('['):
            keyname = line.split('"')[1]
            key = fields.get(keyname)
        elif key is not None:
            # Get everything betweeen the first and last quotes on the line
            value = line.split('"', 1)[1].rsplit('"', 1)[0]
            current[key] = value

这避免了跟踪您在文件中的位置,也意味着您可以处理大量数据文件(如果您在每条记录后处理字典),而不必一次将整个文件加载到内存中。实际上,让我们将其重构为一次处理数据块并生成 dict 供您使用的生成器:

fields = {
    'public_state': 'state',
    'public_zip': 'zip',
    'email': 'email',
    'full_name': 'contact',
    'org_name': 'name',
    'org_website': 'website',
    'city': 'city',
}

def dict_maker(fileobj):
    current = {}
    key = None
    for line in fileobj:
        line = line.lstrip()
        if line.startswith('}'):
            yield current
            current = {}
        elif line.startswith('['):
            keyname = line.split('"')[1]
            key = fields.get(keyname)
        elif key is not None:
            # Get everything betweeen the first and last quotes on the line
            value = line.split('"', 1)[1].rsplit('"', 1)[0]
            current[key] = value

with open("mess.txt") as messy:
    for d in dict_maker(messy):
        print d

这使您的主循环变得很小且易于理解:您遍历可能巨大的一组字典,一次一个,并对它们做一些事情。它将制作字典的行为与使用字典的行为完全分开。而且由于生成器是有状态的,并且一次只处理一行,因此您可以传入任何看起来像文件的东西,比如字符串列表、Web 请求的输出、来自另一个编程写入的输入sys.stdin,或其他任何东西。

于 2013-08-22T18:51:04.037 回答