0

このファイルを解析したい。これがサンプルフラグメントです。

    '13138' => { 'REFERENCE' => '13138', 'NAME' => 'DRAPER Five 125mm Medium Grade Aluminium Oxide Sanding Discs', 'PRICE' => 108, 'MIN_QUANTITY_ORDERABLE' => 1, 'MAX_QUANTITY_ORDERABLE' => 0, 'OUT_OF_STOCK' => 0, 'DATE_PROMPT' => '', 'OTHER_INFO_PROMPT' => '', 'PRICING_MODEL' => 0, 'TAX_1' => '101=2000.00=0=', 'OPAQUE_SHIPPING_DATA' => '0.054', 'ALT_WEIGHT' => '', 'SHIP_SEPARATELY' => 0, 'SHIP_CATEGORY' => '', 'SHIP_SUPPLEMENT' => 0, 'SHIP_SUPPLEMENT_ONCE' => 0, 'HAND_SUPPLEMENT' => 0, 'HAND_SUPPLEMENT_ONCE' => 0, 'SHIP_QUANTITY' => 1, 'COST_PRICE' => 0, 'EXCLUDE_FROM_SHIP' => 0, 'ASSEMBLY_PRODUCT' => 0, 'STOCK_AISLE' => '', 'STOCK_RACK' => '', 'STOCK_SUB_RACK' => '', 'STOCK_BIN' => '', 'BARCODE' => '', 'REPORT_DESC' => '', 'PRICES' => {
    1 => [
        [0,108],
    ],
},
    'CUSTOMVARS' => 
        {
        },
'NO_ORDERLINE' => 0, 'AUTOSHIP' => 0, 'PRODUCT_GROUP' => -1, 'THUMBNAIL' => '', 'IMAGE' => '13138_694.jpg', 'ALSOBOUGHT' => [], 'RELATED' => [],  }, 
    '13139' => { 'REFERENCE' => '13139', 'NAME' => 'DRAPER Five 125mm Coarse Grade Aluminium Oxide Sanding Discs', 'PRICE' => 96, 'MIN_QUANTITY_ORDERABLE' => 1, 'MAX_QUANTITY_ORDERABLE' => 0, 'OUT_OF_STOCK' => 0, 'DATE_PROMPT' => '', 'OTHER_INFO_PROMPT' => '', 'PRICING_MODEL' => 0, 'TAX_1' => '101=2000.00=0=', 'OPAQUE_SHIPPING_DATA' => '0.066', 'ALT_WEIGHT' => '', 'SHIP_SEPARATELY' => 0, 'SHIP_CATEGORY' => '', 'SHIP_SUPPLEMENT' => 0, 'SHIP_SUPPLEMENT_ONCE' => 0, 'HAND_SUPPLEMENT' => 0, 'HAND_SUPPLEMENT_ONCE' => 0, 'SHIP_QUANTITY' => 1, 'COST_PRICE' => 0, 'EXCLUDE_FROM_SHIP' => 0, 'ASSEMBLY_PRODUCT' => 0, 'STOCK_AISLE' => '', 'STOCK_RACK' => '', 'STOCK_SUB_RACK' => '', 'STOCK_BIN' => '', 'BARCODE' => '', 'REPORT_DESC' => '', 'PRICES' => {
    1 => [
        [0,96],
    ],
},
    'CUSTOMVARS' => 
        {
        },
'NO_ORDERLINE' => 0, 'AUTOSHIP' => 0, 'PRODUCT_GROUP' => -1, 'THUMBNAIL' => '', 'IMAGE' => '13139_694.jpg', 'ALSOBOUGHT' => [], 'RELATED' => [],  }, 
    '13140' => { 'REFERENCE' => '13140', 'NAME' => 'DRAPER Five Extra Coarse Grade Aluminium Oxide Sanding Discs', 'PRICE' => 96, 'MIN_QUANTITY_ORDERABLE' => 1, 'MAX_QUANTITY_ORDERABLE' => 0, 'OUT_OF_STOCK' => 0, 'DATE_PROMPT' => '', 'OTHER_INFO_PROMPT' => '', 'PRICING_MODEL' => 0, 'TAX_1' => '101=2000.00=0=', 'OPAQUE_SHIPPING_DATA' => '0.055', 'ALT_WEIGHT' => '', 'SHIP_SEPARATELY' => 0, 'SHIP_CATEGORY' => '', 'SHIP_SUPPLEMENT' => 0, 'SHIP_SUPPLEMENT_ONCE' => 0, 'HAND_SUPPLEMENT' => 0, 'HAND_SUPPLEMENT_ONCE' => 0, 'SHIP_QUANTITY' => 1, 'COST_PRICE' => 0, 'EXCLUDE_FROM_SHIP' => 0, 'ASSEMBLY_PRODUCT' => 0, 'STOCK_AISLE' => '', 'STOCK_RACK' => '', 'STOCK_SUB_RACK' => '', 'STOCK_BIN' => '', 'BARCODE' => '', 'REPORT_DESC' => '', 'PRICES' => {
    1 => [
        [0,96],
    ],
},
    'CUSTOMVARS' => 
        {
        },
'NO_ORDERLINE' => 0, 'AUTOSHIP' => 0, 'PRODUCT_GROUP' => -1, 'THUMBNAIL' => '', 'IMAGE' => '13140_694ii.jpg', 'ALSOBOUGHT' => [], 'RELATED' => [],  }, 

ここには3つのアイテムが含まれています。のような文字列で始まります'13138' => { 'REFERENCE'。同じタイプの文字列の前で終了します。それらの部分をどのように分割できますか?

やってみre.search(r"{ 'REFERENCE'.*?(?={ 'REFERENCE')", catstr)ました。しかし、それは一致しません。

4

1 に答える 1

3

=>に置き換えてみませんか::

    'CUSTOMVARS' :
        {
        },
'NO_ORDERLINE' : 0, 'AUTOSHIP' : 0, 'PRODUCT_GROUP' : -1, ...

そして、それを使用して評価しast.literal_evalます。実行可能コードではなくリテラルのみを評価するため、サニタイズは必要ありません (過度に大きな入力に対するガードを除く)。

ast.literal_eval(node_or_string)

式ノードまたは Python 式を含む文字列を安全に評価します。提供される文字列またはノードは、次の Python リテラル構造のみで構成されている可能性があります: 文字列、数値、タプル、リスト、辞書、ブール値、およびなし。

これは、値を自分で解析する必要なく、信頼できないソースからの Python 式を含む文字列を安全に評価するために使用できます。

編集: 実例

#!/usr/bin/env python2
# -*- encoding: utf8 -*-

import urllib2
import ast
import re
from pprint import PrettyPrinter

pp = PrettyPrinter()
resp = urllib2.urlopen("http://pastie.org/pastes/7461356/download")
content = resp.read()
content = re.search(r"\s+=\s+({(?:.|\n)+});", content).group(1)
# Fix following line to handle => inside strings, if needed
content = re.sub(r"=>", r":", content) 
parsed = ast.literal_eval(content)
pp.pprint(parsed)

外側の文字列のみを置換する方法について=>は、次の回答を参照してください。

編集

指定されたファイルには、ハッシュ自体以外の他のトークンが含まれています。上記の正規表現 re.searchは余分なトークンを取り除きます:

\s+=\s+      # This marks the = before the start of the hash
({           # Capture the first {
  (?:.|\n)+  # This matches all characters.
             # The (?: is to prevent capture-inside-capture
})           # Capture the last }
;            # This is not captured
于 2013-04-12T06:57:57.710 に答える