2015-08-24 23 views
5

मैं कुछ HTML वर्णों से बचने के लिए एक साधारण स्क्रिप्ट के साथ खेल रहा हूं, और मेरी सूची escape_pairs में तत्वों के क्रम के कारण होने वाली एक बग का सामना कर रहा हूं। मैं लूप के दौरान modifying the lists नहीं हूं, इसलिए मैं यहां देख रहे किसी भी पायथन/प्रोग्रामिंग सिद्धांतों के बारे में नहीं सोच सकता।क्या सूची में तत्वों का क्रम लूप में बग का कारण बन सकता है?

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("&") 

रिटर्न

&amp;gt; 
&amp;lt; 
&amp;quot; 
&amp; 

हालांकि जब मैं बग करने के लिए अपने escape_pairs सूची में तत्वों का क्रम बदलने के

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

&gt; 
&lt; 
&quot; 
&amp; 
+0

हां। यदि आप कागज के टुकड़े पर 's' का मान लिखते हैं और अपने कार्यक्रम के चरणों का पालन करते हैं, तो आप इसे देखेंगे। – jtbandes

+0

आपके पहले "छोटी गाड़ी" मामले में, 'प्रतिस्थापन' को यह जानना कैसा है कि आप केवल '*' वर्णों के * कुछ * को प्रतिस्थापित करना चाहते हैं, न कि उन सभी को? – DSM

उत्तर

2

हाँ गायब हो जाता है, अपने पहले कार्यान्वयन में, यह कर सकते हैं।

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

जब escape_pairs के माध्यम से पुनरावृत्ति, आपको पहले > हो और &gt; साथ बदलें -

> के मामले और सूची लेते हैं। इससे स्ट्रिंग '&gt; बन जाती है। फिर आप फिर से चलते रहते हैं, और अंत में आपको ("&","&amp;") मिलते हैं, और &amp; के साथ स्ट्रिंग में & को प्रतिस्थापित करते हैं, जिससे परिणाम आपको प्राप्त होता है।

जब आप सूचियों का क्रम बदलते हैं, तो आपको सही परिणाम मिल जाता है। लेकिन फिर भी यह इसलिए है क्योंकि आपने पहले & पर विचार किया था और इसके बाद ही आपने इसे ध्यान में रखा था।

एक शब्दकोश के अनुसार, आप स्ट्रिंग कोरेक्टली का अनुवाद करने के बजाय str.translate का उपयोग कर सकते हैं। उदाहरण -

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

लेकिन अगर क्या आप HTML स्ट्रिंग से बच रहा है क्या करना चाहते हैं, तो आप मानक पुस्तकालय का उपयोग करना चाहिए - cgi -

>>> import cgi 
>>> cgi.escape("< > &") 
'&lt; &gt; &amp;' 

इसके अलावा, आप अजगर उपयोग कर रहे हैं 3.2 +, आप html.escape का उपयोग कर सकते हैं, उदाहरण -

>>> import html 
>>> html.escape("< > &") 
'&lt; &gt; &amp;' 
+2

दस्तावेज़ों के अनुसार, html.escape का उपयोग सीजीआई के बजाय किया जाना चाहिए। अन्यथा एक महान उत्तर – erlc

+1

मैंने पहली बार इसकी अनुशंसा की थी, लेकिन चूंकि 'एचटीएमएल' मॉड्यूल केवल पायथन 3.2 + है, इसलिए मैं 'cgi' में बदल गया, इसे ध्यान में रखकर नोट किया कि इसका एकमात्र पायथन 3.2 + है। –

+0

मैंने '.translate() 'फ़ंक्शन के बारे में सुना होगा लेकिन कभी भी समझ नहीं आया कि उपयोग का मामला क्या होगा। मान लीजिए मेरे पास अब एक है :) – dylankb

1

मैं पहली बार जब आप एक उदाहरण के रूप में अपने escape_html फ़ंक्शन को कॉल का उपयोग करेगा:
print escape_html(">")

समस्या:
आप (मैं, ओ) पहली बार s.replace जब:

s = ">" 

s = s.replace(i,o) 

">".replace(">", "&gt;") 

s = "&gt;" 

लेकिन अब जब आप की जगह (पिछले करने के लिए मिल), s का मूल्य पहले इतने से बचा लिया गया था:

s = "&gt;" 

s = s.replace(i,o) 

"&gt;".replace("&","&amp;") #replaces the "&" in `"&gt;"` with `"&amp;"` 

s = "&amp;gt;" 


क्यों आदेश महत्वपूर्ण है?
कारण इस आदेश पर निर्भर करता है, क्योंकि जब .replace("&","&amp;") पहले आता है यह हो जाएगा:

s = ">" 

s = s.replace(i,o) 

">".replace("&","&amp;") #No "&"'s to replace so: 

s = ">" 

फिर अपने कार्यक्रम अपेक्षा के अनुरूप काम करने के लिए चला जाता है।

समाधान:
क्योंकि सूची में हमेशा बदलाव करने का प्रयास करने का एक उदाहरण होगा, बस उस परिवर्तन को करने के बाद वापस लौटें।

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

मैं सबसे सरल फिक्स पर ध्यान केंद्रित करने की सराहना करता हूं, भले ही यह सबसे व्यापक न हो। – dylankb

+0

@insighter प्रशंसा के लिए धन्यवाद! मैं एक समाधान प्रदान करना चाहता था जो आप पहले से ही कर रहे थे में आराम से गिर गया ताकि आप इसे जल्दी से समझ सकें और आगे बढ़ सकें। अगर इससे आपकी मदद की जाती है, तो वोट अच्छा होगा, इसलिए दूसरों को पता है कि यह काम करता है! – ThatGuyRussell

संबंधित मुद्दे