2012-10-23 19 views
8

文字列テンプレートが置換に使用する可能性のあるすべてのキーワード引数のリストを取得したいと考えています。テンプレートからキーを取得

これ以外の方法はありますか?

text="$one is a $lonely $number." 
keys = get_keys(text) 
# keys = ('one', 'lonely', 'number') 

私は、単純なマッド-libのようなプログラムを書いている、と私はstring.formatまたはTemplate stringsのいずれかでテンプレート置換を実行したい:

私はこのような何かをしたいです。私は '物語'を書いて、私のプログラムで、ユーザが作り出す必要のあるすべての「キーワード」(名詞、動詞など)のテンプレートファイルを作りたいと思います。私は正規表現でこれを行うことができることを知っていますが、代替ソリューションがあるかどうか疑問に思っていましたか?私はstring.formatとstringテンプレートの代替案を公開しています。

私はそこに解決策があると思っていましたが、すばやい検索でそれを見つけられませんでした。私はこの質問、reverse template with pythonを見つけましたが、実際には私が探しているものではありません。これはreで行うことができることを再確認します。

EDIT:

私は$$は '$' のエスケープである、と私はしたいのトークンではないことに注意してください。 $$5は "$ 5"にレンダリングする必要があります。

答えて

17

は、使用することを検討してください。

+0

私が探していたものはまあまあです。たぶん私の質問はうまくいく必要がありますが、私は基本的に車輪を再構築したくありませんでした。ありがとう。 – Yann

+0

文字列がキーで始まる場合、これは機能しません。 '{foo} test 'で上記を試してください。 – syntacticmarmalade

+0

@syntacticmarmalade Python 3.6でうまく動作します。リストに最後に 'None'があることを意味するのは、文字列がキーで終わらないからです。 'None'のインスタンスをフィルタすることができます。 –

1

str.split()とともにstr.strip()を試してみてください。

In [54]: import string 

In [55]: text="$one is a $lonely $number." 

In [56]: [x.strip(string.punctuation) for x in text.split() if x.startswith("$")] 
Out[56]: ['one', 'lonely', 'number'] 
+0

** $ **で** string.punctuationの一部**、** lstripを作る(」、マッチンググループ

>>> print string.Template.pattern.pattern \$(?: (?P<escaped>\$) | # Escape sequence of two delimiters (?P<named>[_a-z][_a-z0-9]*) | # delimiter and a Python identifier {(?P<braced>[_a-z][_a-z0-9]*)} | # delimiter and a braced identifier (?P<invalid>) # Other ill-formed delimiter exprs ) 

そして、あなた例えば

取得するパターンを印刷することができます$ ')**冗長 – volcano

+0

@ volcanoがチェックされました。 –

0

は、あなたが試みることができる:

def get_keys(s): 
    tokens = filter(lambda x: x[0] == "$", s.split()) 
    return map(lambda x: x[1:], tokens) 
1

は、なぜあなたは正規表現を避けたいのですか?彼らは、このために非常によく動作します:

>>> re.findall(r'\$[a-z]+', "$one is a $lonely $number.") 
['$one', '$lonely', '$number'] 

テンプレートについては、re.subをチェックアウトし、あなたが望むほとんどのことを行うために、コールバックを呼び出すことができます。

>>> from string import Formatter 
>>> [i[1] for i in Formatter().parse('Hello {1} {foo}')] 
['1', 'foo'] 

は詳細についてはhereを参照してください:それはstring.formatを使用しても大丈夫です場合は、内蔵parse()メソッドを持つクラスstring.Formatter

+0

正規表現を避けたいのですが、別の方法があるかどうか疑問に思っていました。 – Yann

+0

長い首でアフリカの動物が欲しいのなら、確かにワニを伸ばすことは可能ですが、ほとんどの場合、キリンと一緒に行く方が簡単です。 – che

0
>>> import string 
>>> get_keys = lambda s:[el.strip(string.punctuation) 
         for el in s.split()if el.startswith('$')] 
>>> get_keys("$one is a $lonely $number.") 
['one', 'lonely', 'number'] 
1

コールを記録するインストゥルメントディクショナリまたはdefaultdictでレンダリングしてから、何を要求したかを確認できます。

5

string.Templateクラスは、属性として使用されるパターンを有する。あなたは

>>> string.Template.pattern.findall("$one is a $lonely $number.") 
[('', 'one', '', ''), ('', 'lonely', '', ''), ('', 'number', '', '')] 
関連する問題