2016-06-27 5 views
1

私は単純なDSLを実装しています。私が手にどこ文字列内の記号を確認する

def tokenize(txt): 
    ... 
    return fmt, vars 

:私は次の関数を実装する必要が

{ 
    'name': 'John', 
    'city': 'Paris', 
    'more': 'xxx', 
    'data': 'yyy', 
    ... 
} 

:私は、次の入力文字列を持っている:

txt = 'Hi, my name is <<name>>. I was born in <<city>>.' 

をそして私は、次のデータを持っている

fmt = 'Hi, my name is {name}. I was born in {city}.' 
vars = ['name', 'city'] 

つまり、はstr.format()関数に渡すことができ、varsは検出されたトークンのリストです(データを検索できるようになりました。これはいくつかの名前空間に分割できるため、説明したよりも複雑になります)

この後

、フォーマットを処理することは簡単で、次のようになります。

get_paramsはデータの簡単な検索を実行すると、のようなものを返している
def expand(fmt, vars, data): 
    params = get_params(vars, data) 
    return fmt.format(params) 

params = { 
    'name': 'John', 
    'city': 'Paris', 
} 

マイquesti on:

tokenizeを実装するにはどうすればよいですか? delitimersが<<>>であることを知って、どのようにしてトークンを検出できますか? regexesのために行くべきか、それとも簡単な道がありますか?

これはpystache、または.format自体がやっていることに似ていますが、私は軽量な実装が欲しいです。この段階では、堅牢性はあまり重要ではありません。

+0

おそらく正規表現を使用できます。 '/ \ <\ <([A-Za-z0-9] +)\> \>/g'のようなものを探してください。これをチェックしてください:https://regex101.com/r/rT8sH9/1 –

+0

@MichaelZhang:ありがとう、偉大な正規表現ヘルパー! – dangonfast

+0

@MichaelZhang - あなたが最初に投稿しました。答えとしてより完全な回答を書きたいので、delavnogはそれを受け入れることができますか? – Prune

答えて

2

はい、これは正規表現のための完全なターゲットです。開始/終了の引用符を見つけ、中括弧で置き換え、シンボル名をリストに抽出します。あなたは法的なシンボルの堅実な記述をしていますか?

/\<\<([a-zA-Z]+[a-zA-Z0-9_]*)\>\>/ 

(これは先頭のアンダースコアを除きます)の検索が必要です。あなたは正規表現でそれに慣れていますか?

+0

確かに、ありがとう、良い出発点。私はこれでウサギの穴に入っていないことを確認したかったのですが、私が現時点では見ていなかったトークンを識別するためのより良い選択肢があると思いました。 – dangonfast

+1

あなたはエスケープする必要はありません。 're.sub(" <<(.*?)> "、" {"r" \ 1 ""} "、s)'は '<<>>'を '{} 'に置き換えます。 –

1
import re 

def tokenize(text): 
    found_variables = [] 
    def replace_and_capture(match): 
     found_variables.append(match.group(1)) 
     return "{{{}}}".format(match.group(1)) 
    return re.sub(r'<<([^>]+)>>', replace_and_capture, text), found_variables 

fmt, vars = tokenize('Hi, my name is <<name>>. I was born in <<city>>.') 
print(fmt) 
print(vars) 

# Output: 
# Hi, my name is {name}. I was born in {city}. 
# ['name', 'city'] 
+0

が役に立ちますあなたは少し説明 –

+0

を追加した場合、OPと将来の読者は、それは宣伝通りに動作しますが、フィルタ機能の選択は、代わりにあなたがそれを言うのはなぜ正規表現基を介して – dangonfast

+0

@delavnogをループで、少し奇妙ですか?見つかったグループをループする場合は、「手作業で」置換する必要があります。これはより単純に思えました。 – smarx

関連する問題