前面关卡的解题报告在这里http://blog.youkuaiyun.com/richytang/article/details/12237519
第2关:http://www.pythonchallenge.com/pc/def/ocr.html
提示中已经很明确的告诉你,对你有帮助的东西可能在网页源代码里。我们查看一下网页源代码,往下一拉页面,Fxxk,那一堆注释的内容应该就是了。要从这里面发现点什么...第一感觉很恐怖的样子。再看网页给出的提示recognize the characters.。那么是不是会重那么一堆东西里面找到字母?
那么我们第一个版本的代码立刻就可以写出来了。
with open('varFor2.txt','r') as fp:
text = fp.read()
ans =''
for c in text:
if c.isalpha():
ans += c
print(ans)
我将那一堆东东存到了varFor2.txt的文件里,然后从文件读出来放到text变量里。这里提一句用with...as...方法打开文件,这样文件的打开和关闭会交给python自动帮你管理,网上说这种方法比close更安全,稳健。然后后面的那个循环很简单了。最后输出结果,答案是:equality。我们用老办法去试一下,下一关正确enter!(不过这里有个插曲,怎么我做着做着网站挂掉了?)
但是题目解出来了,可是看着一点也不pythonic。如果能一行解出这个题才能显现出python的强大威力。想到一个函数,最开始很忽略它的威力,但是不断见识到了这个函数的易用:''.join()。老规矩,help一下:
>>> help(''.join)
Help on built-in function join:
join(...)
S.join(iterable) -> str
Return a string which is the concatenation of the strings in the
iterable. The separator between elements is S.
意思就是,S会插入到后面的迭代变量的中间。那么既然如此''.join(['a','b','c'])返回的就应该是'abc'了。
根据这个函数,我们写出下一个版本的(注意可迭代对象iterable,常见的就是list,str等):
with open('varFor2.txt','r') as fp:
text = fp.read()
print(''.join([c for c in text if c.isalpha()]))
虽然不是一行,但是我是从文件里读出变量嘛。
后来查了一下题解(讲url中的pc改成pcc)。大神们实现的方法真是多种多样啊。还有用正则的:
import re
with open('varFor2.txt','r') as fp:
text = fp.read()
print (''.join(re.findall(r'[a-z]+', text)) )
那么既然可以findall,也可以直接将非字母替换成空字符。最后一句改成:
print(re.sub(r'[^a-z]+', '',text))
好了,这关到此为止,我们进入下一关。
第3关:http://www.pythonchallenge.com/pc/def/equality.html
提示是一个小写字母,周围是三个大写字母。还要注意到这关的名叫:re。那么就是用正则表达式了。源字符串还是在源代码里。
import re
ans = ''.join( re.findall(r'[^A-Z][A-Z]{3}([a-z]{1})[A-Z]{3}[^A-Z]',text))
print(ans)
答案是linkedlist。那么下一关的url也就知道了。看了一下解题报告,发现这个写法就是最简单的了。
上面的关键就是构造正则,题目中的一个提示EXACTLY 很重要。它表示只能是...xXXXxXXXx...的形式,x前后正好三个大写字母。另外就是在构造正则的时候,我们想找的其实就是夹在中间的小写字母,那么这个小写字母的正则表示最好加上括号,这样在匹配的时候,正则引擎知道返回括号里的就够了,不然你试试上面的句子不加括号。最后,匹配完再放到上一题我们就用过的join方法构造一下,就出来了~下一关的url就是:http://www.pythonchallenge.com/pc/def/linkedlist.html。不过跳转过去他告诉你是linkedlist.php。啊,那就改成.php吧,ok了!