2013-05-26 13 views
7

脚注を作成するPythonスクリプトを作成します。考え方は、並べ替え"Some body text.{^}{Some footnote text.}"のすべての文字列を見つけ、"Some body text.^#"に置き換えます。ここで、"^#"は適切な脚注番号です。 (。私のスクリプトの異なる部分は、実際にファイルの下部に脚注をプリントアウトを扱う)私はこのために使用している現在のコードは次のようになります。Pythonでre.sub()を適切に反復する方法

pattern = r"\{\^\}\{(.*?)\}" 
i = 0 
def create_footnote_numbers(match): 
    global i 
    i += 1 
    return "<sup>"+str(i)+"</sup>" 

new_body_text = re.sub(pattern, create_footnote_numbers, text) 

これは正常に動作しますが、持っている奇妙なようですcreate_footnote_numbers関数の外に変数(i)を宣言し、その関数内で変数を呼び出さなければなりません。私は一致の番号を返すreの中に何かがあると思っていたでしょう。あなたが番号を追跡するためにクラスを使用することができるように

答えて

10

どれでも呼び出し可能で、使用することができます。

class FootnoteNumbers(object): 
    def __init__(self, start=1): 
     self.count = start - 1 

    def __call__(self, match): 
     self.count += 1 
     return "<sup>{}</sup>".format(self.count) 


new_body_text = re.sub(pattern, FootnoteNumbers(), text) 

今すぐカウンター状態がFootnoteNumbers()インスタンスに含まれる、とself.countはあなたが起動するたびに新たに設定されます。 re.sub()が実行されます。

+0

興味深い、ありがとうございました。なぜあなたはあなたの 'def __init __()'に 'start ='を持っていますか?それを省略し、 '__init __()'の中で 'self.count = 1'を作るのはなぜでしょうか?これが愚かな質問である場合はお詫びします。私はまだクラスがPythonでどのように動作するかを把握しようとしています。 – Alan

+0

@Alan:これで 'FootnoteNumbers(10)'を行うことができ、最初の脚注にその番号が与えられます。それは柔軟性の素晴らしい余分なビットです。あなたがしたい場合は省略することができます。 –

+0

ああ、とてもいい。ありがとうございました。 – Alan

3

それはa closureのために良いフィットのように思える:

def make_footnote_counter(start=1): 
    count = [start - 1] # emulate nonlocal keyword 
    def footnote_counter(match): 
     count[0] += 1 
     return "<sup>%d</sup>" % count[0] 
    return footnote_counter 

new_body_text = re.sub(pattern, make_footnote_counter(), text) 
+0

'make_footnote_counter'は、' make_footnote_counter'の中で定義しているので、 'make_footnote_counter'が呼び出されるたびに' count'を '[start - 1]'にリセットしませんか?なぜ、これは毎回「」を私に与えてくれませんか?閉鎖の仕組みを理解することは可能です。ありがとう。 – Alan

+0

@Alan: 're.sub()'は、単一の 'make_footnote_counter()'呼び出しによって返される 'footnote_counter'関数を呼び出します。 'count'は' footnote_counter'の呼び出しの間に保持されます。他の例を見るには、答えのリンクに従ってください。 – jfs

3

変動とPython-3のみのソリューション:

def make_create_footnote_numbers(start=1): 
    count = start - 1 
    def create_footnote_numbers(match): 
     nonlocal count 
     count += 1 
     return "<sup>{}</sup>".format(count) 
    return create_footnote_numbers 

new_body_text = re.sub(pattern, make_create_footnote_numbers(), text) 
関連する問題