2012-01-06 10 views
1

を解析する複数の選択肢のマークアップは、このテキストを考えてみましょう:パイソン -

あなたは電子メールで送信されたご質問への回答を持っていますか?

私はそのようにそれらをマークアップによって複数の単語のための複数の選択肢を提案するつもりです:

あなたは[取得する]たい| [た] |あなたへの応答を[持っている]グラムあなたはメールであなたに[最高] [g] [on] [on]あなたに質問を送りましたか?

選択肢がをbrackettedされ、パイプ
で区切ら良い選択は、私はそのようにフォーマットされたテキストを取得するには、この文を解析したいグラム

によって先行される:

__あなたの質問に対する回答はメールで送られますか?以下のようなリストで

[ 
    [ 
    {"to get":0}, 
    {"having":0}, 
    {"to have":1}, 
    ], 
    [ 
    {"up to":0}, 
    {"to":1}, 
    {"on":0}, 
    ], 
] 

は私のマークアップデザインは大丈夫ですか?
文を正規表現して必要な結果を得てリストを生成するにはどうすればよいですか?

編集

+0

私はここに暴言に行くことを意味しませんが、... XMLはかなり良いです。それは名前の中に「マークアップ言語」を持っています。そして、その拡張可能な。それも名前の通りです。あなたのお問い合わせが思想実験であれば、それはうまくいくと思います。 JSONパーサーを独自の形式で作成することは間違った方向に向いています。 XMLはすばらしいですが、私は誰もが言うことを気にしません。ララララ私はあなたのことを聞くことができません! – synthesizerpatel

+0

私はあまりにも暴言状になりたくはありませんが、思考実験よりも宿題問題への答えを探している人のように見えます。そうであれば、 '宿題'タグを付けてください。そして、それがオリジナルの思考か割り当てかにかかわらず、あなたの正規表現コード、あなたがすでに試したもの、そしてあなたが遭遇した問題を投稿してください。 – Dave

+0

これは宿題に関する質問ではありません。 TinyMCEやMarkdownのようなすべてのマークアップツールは、そのマークアップ形式を持ち、冗長性のために良い__old__ XMLを使用しません。 @synthesizerpatelのご提案ありがとうございますが、私はJSONパーサを構築していません。私はマークアップされたテキストを解析していくつかの変数を取得しようとしています。 –

答えて

2

あなたはいかが{取得するには| +持っている|持つ}に対する応答をあなたの質問 は{あなたのメールアドレス}まであなたにメールを送りましたか?

def extract_choices(text): 
    choices = [] 

    def callback(match): 
     variants = match.group().strip('{}') 
     choices.append(dict(
      (v.lstrip('+'), v.startswith('+')) 
      for v in variants.split('|') 
     )) 
     return '___' 

    text = re.sub('{.*?}', callback, text) 

    return text, choices 

それを試してみましょう:

>>> t = 'Would you like {to get|having|+to have} responses to your questions sent {up to|+to|on} you via email?' 
>>> pprint.pprint(extract_choices(t)) 
... ('Would you like ___ responses to your questions sent ___ you via email?', 
... [{'having': False, 'to get': False, 'to have': True}, 
... {'on': False, 'to': True, 'up to': False}]) 
+0

私はそれが好きです。コンパクトなマークアップとコンパクトなコード。 – reclosedev

+0

非常に良い解決策、ありがとう。 –

+0

このマークアップのクレジットは@reclosedevに行きます、私は '{}'について考えを取り、不要なものを取り除きました:) – Ski

1

必要なユーザー指向のマークアップ言語私もなります利用可能なツールの多くがすでに存在するため、このタスクXMLのはるかに適切であると考えて解析する方がはるかに簡単かつ少ないエラーが発生しやすいです。とにかく

、あなたのデザインを使用することを決定した場合、私はこのような何かをしたい:

import re 

question_str = ("Would you like [to get]|[having]|g[to have] " 
       "responses to your questions sent " 
       "[up to]|g[to]|[on] you via email ?") 

def option_to_dict(option_str): 
    if option_str.startswith('g'): 
      name = option_str.lstrip('g') 
      value = 1 
    else: 
      name = option_str 
      value = 0 
    name = name.strip('[]') 
    return {name: value} 

regex = re.compile('g?\[[^]]+\](\|g?\[[^]]+\])*') 

options = [[option_to_dict(option_str) 
      for option_str in match.group(0).split('|')] 
      for match in regex.finditer(question_str)] 
print options 

question = regex.sub('___', question_str) 
print question 

出力例:

[[{'to get': 0}, {'having': 0}, {'to have': 1}], [{'up to': 0}, {'to': 1}, {'on': 0}]] 
Would you like ___ responses to your questions sent ___ you via email ? 

注:デザインに関しては、私はそれが可能だと思いますオプションのセット全体の開始/終了を設定するマークを持つほうが良い(単一のオプションの場合だけでなく)。正規表現を使用して

+2

'name = option_str [2:-1]'と 'name = option_str [1:-1]'を単純な 'option_str.strip( 'g []')'で置き換えることをお勧めしますか? –

+0

@DK確かに、それはコードを読みやすくします。あなたの提案をありがとう。 – jcollado

+0

@DK最後に、 'g'で始まる/終わるとオプション自体から文字を削除するので' g'を 'strip'に追加しませんでした。 – jcollado

2

ラフ解析の実装:今はかなり簡単にする必要がありますあなたのフォーマットに合わせて、これを解析

import re 
s = "Would you like [to get]|[having]|g[to have] responses to your questions sent [up to]|g[to]|[on] you via email ?" # pattern string 

choice_groups = re.compile(r"((?:g?\[[^\]]+\]\|?)+)") # regex to get choice groups 
choices = re.compile(r"(g?)\[([^\]]+)\]") # regex to extract choices within each group 

# now, use the regexes to parse the string: 
groups = choice_groups.findall(s) 
# returns: ['[to get]|[having]|g[to have]', '[up to]|g[to]|[on]'] 

# parse each group to extract possible choices, along with if they are good 
group_choices = [choices.findall(group) for group in groups] 
# will contain [[('', 'to get'), ('', 'having'), ('g', 'to have')], [('', 'up to'), ('g', 'to'), ('', 'on')]] 

# finally, substitute each choice group to form a template 
template = choice_groups.sub('___', s) 
# template is "Would you like ___ responses to your questions sent ___ you via email ?" 

。幸運:)

+0

+1非常に簡単な解決策です。 –

3

私はいくつかのグループ化括弧{}を追加し、dictsのリストのリストではなく、dictsのリストを出力します。

コード:

import re 

s = 'Would you like {[to get]|[having]|g[to have]} responses to your questions sent {[up to]|g[to]|[on]} you via email ?' 

def variants_to_dict(variants): 
    dct = {} 
    for is_good, s in variants: 
     dct[s] = 1 if is_good == 'g' else 0 
    return dct 

def question_to_choices(s): 
    choices_re = re.compile(r'{[^}]+}') 
    variants_re = re.compile(r'''\|?(g?) 
           \[ 
            ([^\]]+) 
           \] 
           ''', re.VERBOSE) 
    choices_list = [] 
    for choices in choices_re.findall(s): 
     choices_list.append(variants_to_dict(variants_re.findall(choices))) 

    return choices_re.sub('___', s), choices_list 

question, choices = question_to_choices(s) 
print question 
print choices 

出力:私はあまりにも私の解決策を提案します

Would you like ___ responses to your questions sent ___ you via email ? 
[{'to have': 1, 'to get': 0, 'having': 0}, {'to': 1, 'up to': 0, 'on': 0}] 
+0

これは私にとって最も効率的なようです。 –

+0

@グライド、あなたはすでに私の答えを受け入れていますが、* Skirmantas *の解決策を見てください。それはコンパクトなマークアップとコードを持っています。 – reclosedev

+0

私はちょうどそれを見た、ありがとう、私はあなたに少なくとも私の+1を残します:) –