Python核心编程第三版练习参考(第一章:正则表达式)

来源:互联网 发布:阿里云邮箱域名解析 编辑:程序博客网 时间:2024/06/16 05:49

1-1 识别后续的字符串:“bat”、“bit”、“but”、“hat”、“hit”或者“hut”。

答:'[bh][aiu]t'


1-2 匹配由单个空格分隔的任意单词对,也就是姓和名。

答:'\w+\s\w+'



1-3 匹配由单个逗号和单个空白符分隔的任何单词和单个字母,如姓氏的首字母。

答:'\w+,\s\w+''


1-4 匹配所有有效Python标识符的集合。

答:'[_A-Za-z]+[_\w]+'


1-5 根据读者当地的格式,匹配街道地址(使你的正则表达式足够通用,来匹配任意数量的街道单词,包括类型名称)。例如,美国街道地址使用如下格式:1180 Bordeaux Drive。使你的正则表达式足够灵活,以支持多单词的街道名称,如3120 De la Cruz Boulevard。

答:r'\d+ .+'


1-6 匹配以“www”起始且以“.com”结尾的简单Web域名;例如,www://www. yahoo.com/。选做题:你的正则表达式也可以支持其他高级域名,如.edu、.net等(例如,http://www.foothill.edu)。

答:(1)r'^www://.+.com$'

        (2)r'^www://.+.[com|edu|org|gov|net]$'


1-7 匹配所有能够表示Python整数的字符串集。

答:也就是说既可以表示正整数也可以表示正整数(我的个脑子啊,基本概念都不清了)

        r'[-\d]\d+'  #为了不输出+,[]是从多个中选一个(基础还得练啊……)


1-8 匹配所有能够表示Python长整数的字符串集。

答:"\d+[1L]"


1-9 匹配所有能够表示Python浮点数的字符串集。

答:r'\d+(.\d*)'


1-10 匹配所有能够表示Python复数的字符串集。

答:r'\d+(\+\d*i)?'   #简单的实部和虚部都是整数

        r'\d+(.\d*)((\+\d(.\d*))*i)?'         #搞得有些复杂,但是可以匹配实数的复数了,小伙伴谁有更简洁的,可以共享啦^-^


1-11 匹配所有能够表示有效电子邮件地址的集合(从一个宽松的正则表达式开始,然后尝试使它尽可能严谨,不过要保持正确的功能)。

答:有效电子邮件地址的规则:

        1.用户名,可以自己选择。由字母a~z(不区分大小写)、数字0~9、点、减号或下划线组成;只能以数字或字母开头和结尾,例如:beijing.2008;用户名长度为4~18个字符 。

         2.与你使用的网站有关,代表邮箱服务商。例如网易的有@163.com/@126.com/@188.com /@Yeah。com等;新浪的是@sina.com/@vip.sina.com等(也就还是字母数字组合)


         r'\w+(\.|\d|-|_)*\w+@\w+\.com'


1-12 匹配所有能够表示有效的网站地址的集合(URL)(从一个宽松的正则表达式开始,然后尝试使它尽可能严谨,不过要保持正确的功能)。

答:


1-13 type()。内置函数type()返回一个类型对象,如下所示,该对象将表示为一个Pythonic类型的字符串。


    >>> type(0)  

    <type 'int'>

    >>> type(.34)  

    <type 'float'>

    >>> type(dir)  

    <type 'builtin_function_or_method'>


创建一个能够从字符串中提取实际类型名称的正则表达式。函数将对类似于<type 'int' >的字符串返回int(其他类型也是如此,如 'float' 、'builtin_function_or_method' 等)。注意:你所实现的值将存入类和一些内置类型的__name__属性中。

答:r"type\s.(\w+)."


1-14 处理日期。1.2节提供了来匹配单个或者两个数字字符串的正则表达式模式,来表示1~9的月份(0?[1-9])。创建一个正则表达式来表示标准日历中剩余三个月的数字。

答:'(1[0-2])'


1-15 处理信用卡号码。1.2节还提供了一个能够匹配信用卡(CC)号码([0-9]{15,16})的正则表达式模式。然而,该模式不允许使用连字符来分割数字块。创建一个允许使用连字符的正则表达式,但是仅能用于正确的位置。例如,15位的信用卡号码使用4-6-5的模式,表明4个数字-连字符-6个数字-连字符-5个数字;16位的信用卡号码使用4-4-4-4的模式。记住,要对整个字符串进行合适的分组。选做题:有一个判断信用卡号码是否有效的标准算法。编写一些代码,这些代码不但能够识别具有正确格式的号码,而且能够识别有效的信用卡号码。

答:(1)r'\d{4}-\d{4,6}-\d{4,5}(-\d{4})?'

        (2)def check(card):
    import re
    ma = re.search(r'\d{4}-(\d{4,6})-(\d{4,5})(-(\d{4}))?',"1234-123456-12345").group()
    if len(ma.group(1))==4:
        if len(ma.group(2))==4 and len(ma.group(4))==4:
            return True
        return False
    elif len(ma.group(1))==6:
        if len(ma.group(2)==5):
            return True
        return False
    else:
        return False

使用gendata.py。下面一组练习(1-16~1-27)专门处理由gendata.py生成的数据。在尝试练习1-17和1-18之前,读者需要先完成练习1-16以及所有正则表达式。


1-16 为gendata.py更新代码,使数据直接输出到redata.txt而不是屏幕。

答:from random import randrange,choice
from string import ascii_lowercase as lc
from sys import maxint
from time import ctime
    
tlds = ('com','edu','net','org','gov')
f = open('redata.txt','a+')
for i in xrange(randrange(5,11)):
    dtint = randrange(maxint)
    dtstr = ctime(dtint)
    llen = randrange(4,8)
    login = ''.join(choice(lc) for j in range(llen))
    dlen = randrange(llen,13)
    dom = ''.join(choice(lc) for j in xrange(dlen))
    print '%s::%s@%s.%s::%d-%d-%d' % (dtstr,login,dom,choice(tlds),dtint,llen,dlen)
    f.write('%s::%s@%s.%s::%d-%d-%d\n' % (dtstr,login,dom,choice(tlds),dtint,llen,dlen))


1-17 判断在redata.tex中一周的每一天出现的次数(换句话说,读者也可以计算所选择的年份中每个月中出现的次数)。

答:就是用模式串匹配月份

        r'\s\w{3}\s'


1-18 通过确认整数字段中的第一个整数匹配在每个输出行起始部分的时间戳,确保在redata.txt中没有数据损坏。
创建以下正则表达式。

答:


1-19 提取每行中完整的时间戳。

答:r'.{24}'     #偷懒了,因为完整时间戳就是24个任意字符


1-20 提取每行中完整的电子邮件地址。

答:re.search(r'::(\w+@\w+\.(com|net|cn|edu|gov))',"Fri Aug 06 02:32:59 2032::fgmdu@ppdyxaz.net::1975343579-5-7").group(1)


1-21 仅仅提取时间戳中的月份。

答:设置子组


1-22 仅仅提取时间戳中的年份。

答:设置子组


1-23 仅仅提取时间戳中的时间(HH:MM:SS)。

答:设置子组


1-24 仅仅从电子邮件地址中提取登录名和域名(包括主域名和高级域名一起提取)。

答:re.search(r'::(\w+)@(\w+)\.(?:com|net|cn|edu|gov)',"Fri Aug 06 02:32:59 2032::fgmdu@ppdyxaz.net::1975343579-5-7").groups()


1-25 仅仅从电子邮件地址中提取登录名和域名(包括主域名和高级域名)。

答:


1-26 使用你的电子邮件地址替换每一行数据中的电子邮件地址。

答:re.sub(r'::\w+@\w+\.(?:com|net|cn|edu|gov)','::123@qq.com',"Fri Aug 06 02:32:59 2032::fgmdu@ppdyxaz.net::1975343579-5-7")


1-27 从时间戳中提取月、日和年,然后以“月,日,年”的格式,每一行仅仅迭代一次。

答:子组


处理电话号码。

对于练习1-28和1-29,回顾1.2节介绍的正则表达式\d{3}-\d{3}-\d{4},它匹配电话号码,但是允许可选的区号作为前缀。更新正则表达式,使它满足以下条件。
1-28 区号(三个整数集合中的第一部分和后面的连字符)是可选的,也就是说,正则表达式应当匹配800-555-1212,也能匹配555-1212。

答:re.match(r'(\d{3}-)?\d{3}-\d{4}','555-1212').group()


1-29 支持使用圆括号或者连字符连接的区号(更不用说是可选的内容);使正则表达式匹配800-555-1212、555-1212以及(800)555-1212。

答:re.match(r'((\d{3}-)|\(\d{3}\))?\d{3}-\d{4}','(800)555-1212').group()


正则表达式应用程序。下面练习在处理在线数据时生成了有用的应用程序脚本。
1-30 生成HTML。提供一个链接列表(以及可选的简短描述),无论用户通过命令行方式提供、通过来自于其他脚本的输入,还是来自于数据库,都生成一个Web页面(.html),该页面包含作为超文本锚点的所有链接,它可以在Web浏览器中查看,允许用户单击这些链接,然后访问相应的站点。如果提供了简短的描述,就使用该描述作为超文本而不是URL。

答:


1-31 tweet精简。有时候你想要查看由Twitter用户发送到Twitter服务的tweet纯文本。创建一个函数以获取tweet和一个可选的“元”标记,该标记默认为False,然后返回一个已精简过的tweet字符串,即移除所有无关信息,例如,表示转推的RT符号、前导的“.”符号,以及所有#号标签。如果元标记为True,就返回一个包含元数据的字典。这可以包含一个键“RT”,其相应的值是转推该消息的用户的字符串元组和/或一个键“#号标签”(包含一个#号标签元组)。如果值不存在(空元组),就不要为此创建一个键值条目。

答:


1-32 亚马逊爬虫脚本。创建一个脚本,帮助你追踪你最喜欢的书,以及这些书在亚马逊上的表现(或者能够追踪图书排名的任何其他的在线书店)。例如,亚马逊对于任何一本图书提供以下链接:http://amazon.com/dp/ISBN(例如,http://amazon.com/ dp/0132678209)。读者可以改变域名,检查亚马逊在其他国家的站点上相同的图书排名,例如德国(.de)、法国(.fr)、日本(.jp)、中国(.cn)和英国(.co.uk)。使用正则表达式或者标记解析器,例如BeautifulSoup、lxml或者html5lib来解析排名,然后让用户传入命令行参数,指明输出是否应当在一个纯文本中,也许包含在一个电子邮件正文中,还是用于Web的格式化HTML中。

答:


阅读全文
0 0
原创粉丝点击