列表中元素的顺序是否会导致for循环中的错误?

dyl*_*nkb 5 python loops replace tuples

我正在玩一个简单的脚本来逃避某些HTML字符,并且遇到了一个似乎是由我列表中的元素顺序引起的错误escape_pairs.我不是在循环中修改列表,所以我想不出我在这里忽略的任何Python /编程原则.

escape_pairs = [(">", "&gt;"),("<","&lt;"),('"',"&quot;"),("&","&amp;")]

def escape_html(s):
    for (i,o) in escape_pairs:
        s = s.replace(i,o)
    return s

print escape_html(">")
print escape_html("<")
print escape_html('"')
print escape_html("&")
Run Code Online (Sandbox Code Playgroud)

回报

&amp;gt;
&amp;lt;
&amp;quot;
&amp;
Run Code Online (Sandbox Code Playgroud)

但是当我切换escape_pairs列表中元素的顺序时,bug就消失了

>>> escape_pairsMod = [("&","&amp;"),("<","&lt;"),('"',"&quot;"),(">", "&gt;")]

&gt;
&lt;
&quot;
&amp;
Run Code Online (Sandbox Code Playgroud)

Ana*_*mar 2

是的,在您的第一次实现中,它可以。

让我们以以下情况>为例 -

escape_pairs = [(">", "&gt;"),("<","&lt;"),('"',"&quot;"),("&","&amp;")]
Run Code Online (Sandbox Code Playgroud)

迭代时escape_pairs,您首先获取>并将其替换为&gt;. 这会导致字符串变成'&gt;. 然后继续迭代,最后找到("&","&amp;"),并将&字符串中的 替换为&amp;,使结果成为您现在得到的结果。

当您更改列表的顺序时,您会得到正确的结果。但这仍然是因为你先考虑了&,然后才考虑了其他。

您可以str.translate根据字典使用 coorectly 来翻译字符串。例子 -

>>> escape_pairs = [(">", "&gt;"),("<","&lt;"),('"',"&quot;"),("&","&amp;")]
>>> escape_dict = dict(escape_pairs)
>>> t = str.maketrans(escape_dict)
>>> ">".translate(t)
'&gt;'
>>> "> & <".translate(t)
'&gt; &amp; &lt;'
Run Code Online (Sandbox Code Playgroud)

但如果你想做的是 HTML 转义字符串,那么你应该使用标准库 - cgi-

>>> import cgi
>>> cgi.escape("< > &")
'&lt; &gt; &amp;'
Run Code Online (Sandbox Code Playgroud)

另外,如果您使用的是Python 3.2 +,则可以使用html.escape示例 -

>>> import html
>>> html.escape("< > &")
'&lt; &gt; &amp;'
Run Code Online (Sandbox Code Playgroud)

  • 根据文档,应该使用 html.escape 而不是 cgi。否则是一个很好的答案 (2认同)