1

次のテキストを検討してください。

質問への回答を電子メールで受け取りますか?

いくつかの単語を次のようにマークアップして、複数の選択肢を提案します。

あなたの質問への回答を [to get]|[having]|g[to have] メールで [up to]|g[to]|[on] 送りますか?

選択肢は括弧で囲まれ、パイプで区切られます
適切な選択肢はgで始まります

この文を解析して、そのようにフォーマットされたテキストを取得したいと思います。

質問への回答を __ メールで __ 送信してよろしいですか?

次のようなリストを使用します。

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

マークアップのデザインは大丈夫ですか?
文を正規表現して必要な結果を取得し、リストを生成する方法は?

edit : ユーザー指向のマークアップ言語が必要

4

4 に答える 4

3

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

コード:

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}]
于 2012-01-06T13:11:18.470 に答える
2

私も私の解決策を提案します:

あなたの質問への回答を{to|+to|on}にメールで{to get|having|+to have}送信してよろしいですか?

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}])
于 2012-01-06T14:05:00.363 に答える
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 ?"

これをフォーマットに合わせて解析することは、今では非常に簡単なはずです。幸運を :)

于 2012-01-06T12:59:45.497 に答える
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 ?

注: デザインに関しては、オプションのセット全体の開始/終了を設定するためのマーク (単一のオプションの 1 つだけでなく) がある方がよいと思います。

于 2012-01-06T12:48:56.667 に答える