I am in the process of writing a search engine for the experience and the knowledge. Right now, I am in the process of building a crawler and its accompanying utilities. One of these is the URL normalizer. This is what I am trying to build right now, and more specifically I am stuck at the point where I have to make a method to take a url, and capitalize letters that follow a '%' sign. My code so far:
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)
Can someone please guide me to where my error is? I would be grateful. Thank you.
EDIT: this is what I am trying to achieve:
http://www.example.com/a%c2%b1b → http://www.example.com/a%C2%B1b
By static analysis, it loops forever because your while True
never breaks. So where can it break? Only at the break
statement only if the next_encounter
becomes equal to -1; so you can deduce that it never does.
Why doesn't it? Try a print next_encounter
after url.find
. You'll quickly see that
url = url[next_encounter:]
does almost what you hope it will, only it gives you one character more than you hoped.
Why did I present it this way? Mostly because the value of print
is often underrated by people learning the language.
@msw nailed it and gave sound advice.
My $.02 is you never should have tried this loop
How about:
>>> re.sub('%..',lambda m: m.group(0).upper(),'http://www.example.com/a%c2%b1b')
'http://www.example.com/a%C2%B1b'
This is why:
>>> 'asd'.find('s')
1
>>> 'asd'[1:]
'sd'
Also, consider using the second argument to str.find()
instead of slicing.
I'm coming a bit late to the party, but you might want to consider using a regular expression instead of such a complicated function:
>>> 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'
Explanation:
(?i) # Make regex case-insensitive
% # Match a %
[0-9A-F]{2} # Match two hex digits
re.sub()
finds all these occurrences in the string and passes the result (the match object's group(0)
) to the .upper()
method, then replaces the original with the uppercased version of the match.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.