2017-07-18 60 views
0

所以我在我的Flask應用程序中有以下功能。使用re.sub和jinja2.Markup在Python 3.6中轉義?

def markup_abbreviations(txt, match_map, match_regex): 
    html = Markup.escape(txt) 
    sub_template = Markup('<abbr title="%s">%s</abbr>') 

    def replace_callback(m): 
     return sub_template % (match_map[m.group(0)], m.group(0)) 

    return match_regex.sub(replace_callback, html) 

實例參數:

txt = 'blah blah blah etc., blah blah' 

match_map = { 
    'etc.': 'et cetera', 
    'usu.': 'usually', 
} 

match_regex = re.compile(
    '|'.join(r'\b' + re.escape(k) for k in match_map) 
) 

這是工作非常好,在我的本地的Python 3.3的機器轉動"etc.""<abbr title=\"et cetera\">etc.</abbr>"等。

然後我想我要部署到Heroku,它說它只支持最新的python,它是Python 3.6.1。這與我在當地獲得的不同,但是,呃,無論如何。它工作...大多數。

除了我上面的函數現在給我"&lt;abbr title=&quot;et cetera&quot;&gt;etc.&lt;/abbr&gt;"

我假設Python 3.3和Python 3.6之間的re.sub實現必須以某種方式更改,現在不再使用傳遞的字符串方法來創建輸出。所以不使用Markup的自動轉義方法。而是從零開始構建新的str。這就是爲什麼re.sub現在只返回str,而不是Markup了。

如何在Python 3.6中使用re.subjinja2.Markup並使我的函數再次工作?

回答

1

Markup類只是「標記」字符串作爲html的安全。這意味着字符串在放入模板時不必轉義。

re.sub()返回新的str對象時,您需要做的是將新對象標記爲安全(將其包裝在標記中)。

def markup_abbreviations(txt, match_map, match_regex): 
    html = Markup.escape(txt) 
    sub_template = '<abbr title="%s">%s</abbr>' 

    def replace_callback(m): 
     return sub_template % (match_map[m.group(0)], m.group(0)) 

    return Markup(match_regex.sub(replace_callback, html)) 

我檢查所有的「新事物」在Python 3.3到3.6並沒有什麼要改變re模塊的行爲(當然有一些,但它不應該與你的問題進行連接)。也許別人知道發生了什麼...

+0

噢!你是對的.'replace_callback'正在返回'Markup',它只是're.sub',它返回爲'str'謝謝! – OdraEncoded