2012-07-14 68 views
2

我正在編寫一個經驗和知識的搜索引擎。目前,我正在構建一個爬行器及其附帶的實用程序。其中之一是URL規範化器。這就是我現在想要構建的內容,更具體地說,我被困在了一個地方,那就是我必須製作一個方法來獲得一個url,並且使用一個'%'符號後的字母大寫。我的代碼到目前爲止:爲什麼這段代碼無限循環?

def escape_sequence_capitalization(url): 
     ''' The method that capitalizes letters in escape sequences. 
     All letters within a percent - encoding triplet (e.g. '%2C') are case 
     insensitive and should be capitalized. 

     ''' 
    next_encounter = None 
    url_list = [] 
    while True: 
     next_encounter = url.find('%') 
     if next_encounter == -1: 
      break 

     for letter in url[:next_encounter]: 
      url_list.append(letter) 

     new_character = url[next_encounter + 1].upper() 
     url_list.append(new_character) 
     url = url[next_encounter:] 

    for letter in url: 
     url_list.append(letter) 

    return ''.join(url_list) 

有人可以指導我,我的錯誤是哪裏?我會很感激。謝謝。

編輯:這就是我想實現:

http://www.example.com/a%c2%b1b → http://www.example.com/a%C2%B1b 

回答

10

通過靜態分析,它會永久循環,因爲您的while True永遠不會中斷。那麼它在哪裏可以突破?僅當next_encounter等於-1時纔在break聲明中;所以你可以推斷它永遠不會。

爲什麼不呢?在url.find之後嘗試print next_encounter。你很快就會看到,

url = url[next_encounter:] 

做你希望幾乎什麼會,只是它給你一個角色比你希望的。

爲什麼我以這種方式呈現?主要是因爲學習語言的人往往低估了print的價值。

+0

謝謝你,你的回答是最有見地的。我並不低估print()的價值,打印方法和函數是我在其他編程語言中使用的主要調試工具,它只是因爲我缺乏經驗而沒有引起我的注意。謝謝。 – NlightNFotis 2012-07-14 18:24:05

+0

@msw。很好的解釋! – doniyor 2012-07-14 18:25:37

3

這就是爲什麼:

>>> 'asd'.find('s') 
1 
>>> 'asd'[1:] 
'sd' 

而且,考慮使用第二個參數str.find()而不是切片。

4

@msw釘了它,並給出了合理的建議。

我的$ .02是你永遠不應該嘗試這個循環

如何:

>>> re.sub('%..',lambda m: m.group(0).upper(),'http://www.example.com/a%c2%b1b') 
'http://www.example.com/a%C2%B1b' 
+0

聽起來像一個計劃,但我是一個Python新手,目前lambda對我來說有點困惑,所以如果我能避免它們,我寧願這樣做。 – NlightNFotis 2012-07-14 18:37:19

+3

lambda不過是一行功能。可能已經在[docs for're]中創建了一個函數。sub'](http://docs.python.org/library/re.html)。擁抱功能範式。抵抗是徒勞的。 – 2012-07-14 18:47:35

+2

Lol'd'擁抱功能範式。抵抗是徒勞的。'部分。很好的一個伴侶。 – NlightNFotis 2012-07-14 18:54:26

1

我來了有點遲到了,但你可能要考慮使用常規表達,而不是這樣的複雜功能:

>>> import re 
>>> url = "http://www.example.com/a%c2%b1b" 
>>> result = re.sub("(?i)%[0-9A-F]{2}", lambda x: x.group(0).upper(), url) 
>>> result 
'http://www.example.com/a%C2%B1b' 

說明:

(?i)   # Make regex case-insensitive 
%    # Match a % 
[0-9A-F]{2} # Match two hex digits 

re.sub()找到字符串在所有這些出現並將結果(匹配對象的group(0))到.upper()方法,然後替換原來的與所述匹配的大寫的版本。

+0

很好的回答。會考慮你的方法。 – NlightNFotis 2012-07-15 09:44:59