5.3 正则表达式和re模块

微视频

正则表达式是字符串,它包含文本和特殊字符。re模块可以执行正则表达式的功能。利用文字与特定字符的混合,可以定义复杂的字符串匹配与取代类型。

5.3.1 正则表达式的特定字符

正则表达式所用的特定字符如表5-2所示。

表5-2 正则表达式所用的特定字符

如果用户要在正则表达式内使用?、*、+或换行等符号,就必须使用表5-3所示的字符。

表5-3 正则表达式内的特殊字符

5.3.2 re模块的方法

re模块的主要功能是通过正则表达式来操作字符串。在使用re模块时,需要先使用import语句引入,语法格式如下:

    import re

下面讲述re模块中常见的操作字符串的方法。

1.匹配字符串

通过re模块中的match()、search()和findall()方法可以匹配字符串。

(1)match()。match()方法用于从字符串的开始处进行匹配,如果在起始位置匹配成功,则返回Match对象;如果不是在起始位置匹配成功,则返回None。

match()方法的语法格式如下:

    re.match(pattern, string, flags=0)

其中,参数pattern用于匹配的正则表达式;参数string用于要匹配的字符串;参数flags用于控制正则表达式的匹配方式,如是否区分大小写、多行匹配等。如果匹配成功,match()方法返回一个匹配的对象,否则返回None。

【例5.5】验证输入的手机号是否为中国移动的号码(源代码\ch05\5.5.py)。

这里首先需要导入re模块,然后定义一个验证手机号码的模式字符串,最后使用match()方法验证输入的手机号是否和模式字符串匹配。

    import re                                    #导入Python 的re 模块
    print("欢迎进入中国移动电话号码验证系统")
    s1 = r'(13[4-9]\d{8})$|(15[01289]\d{8}$)'
    s2 = input("请输入需要验证的电话号码:")     #输入需要验证的电话号码
    match = re.match(s1,s2)                      #进行模式匹配
    if match==None:                              #判断是否为None,为真表示匹配失败
       print("您输入的号码不是中国移动的电话")
    else:
       print("您输入的号码是中国移动的电话")

程序运行结果如图5-5所示。

图5-5 例5.5的程序运行结果

(2)search()。search()方法用于扫描整个字符串并返回第一个成功的匹配。语法格式如下:

    re.search(pattern, string, flags=0)

其中,参数pattern用于匹配的正则表达式;参数string用于要匹配的字符串;参数flags用于控制正则表达式的匹配方式,如是否区分大小写、多行匹配等。如果匹配成功,match()方法返回一个匹配的对象,否则返回None。

与match()方法不同的是,search()方法既可以在起始位置匹配,也可以不在起始位置匹配。

例如下面的代码:

    import re
    print(re.search('www', 'www.bczj123.com').span())  #在起始位置匹配
    print(re.search('123', 'www.bczj123.com').span())  #不在起始位置匹配

运行结果如下:

    (0, 3)
    (8, 11)

【例5.6】敏感字过滤系统(源代码\ch05\5.6.py)。

假设敏感字为渗透、攻击、脚本,如果输入的字符串中含有敏感字中的任意一个,将会有警告提示,否则安全通过。

    import re                                         #导入Python 的re 模块
    print("欢迎进入敏感字过滤系统")
    s1 = r'(渗透)|(攻击)|(脚本)'                      #模式字符串
    s2 = input("请输入需要验证的文字:")              #输入需要验证的字符串
    match = re.search(s1,s2)                          #进行模式匹配
    if match==None:                                   #判断是否为None,为真表示匹配失败
       print("您输入的文字安全通过!!")
    else:
       print("警告!您输入的文字存在敏感字,请重新整理后输入!")

程序运行结果如图5-6所示。

图5-6 例5.6的程序运行结果

大牛提醒

match()方法只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而search()方法匹配整个字符串,直到找到一个匹配项。

(3)findall()。findall()方法用于在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配项,则返回空列表。

大牛提醒

match()和search()方法是匹配一次,而findall()方法匹配所有。

findall()的语法格式如下:

    findall(string[, pos[, endpos]])

其中,参数string是待匹配的字符串;pos为可选参数,指定字符串的起始位置,默认为0;endpos为可选参数,指定字符串的结束位置,默认为字符串的长度。

【例5.7】数字挑选系统(源代码\ch05\5.7.py)。

对输入的字符串进行挑选,如果发现数字,挑选出来。

    import re                                 #导入Python 的re 模块
    print("欢迎进入数字挑选系统")
    s1 = re.compile(r'\d+')                   #查找数字
    s2 = input("请输入需要挑选的字符串:")    #输入需要挑选的字符串
    result = s1.findall(s2)
    print(result)

程序运行结果如图5-7所示。

图5-7 例5.7的程序运行结果

2.替换字符串

通过re模块中的sub()方法可以替换字符串中的匹配项。语法格式如下:

    re.sub(pattern, repl, string, count=0, flags=0)

其中,参数pattern是正则表达式中的模式字符串;repl是要替换的字符串,也可为一个函数;参数string要被查找替换的原始字符串;参数count是模式匹配后替换的最大次数,默认为0,表示替换所有的匹配项。

【例5.8】替换字符串中的非数字和特殊符号(源代码\ch05\5.8.py)。

    import re
    numb = "0408-1111-1189 #这是一个学生的编号"
    #删除字符串中的 Python 注释
    nums = re.sub(r'#.*$', "", numb)
    print ("学生的编号是: ", nums)
    #删除非数字(-)的字符串
    numd = re.sub(r'\D', "", numb)
    print ("学生的新编号是: ", numd)

程序运行结果如图5-8所示。

图5-8 例5.8的程序运行结果

3.分割字符串

通过re模块中的split()方法可以分割字符串。split()方法按照能够匹配的子串将字符串分割后返回列表。语法格式如下:

    re.split(pattern, string[, maxsplit=0, flags=0])

其中,参数pattern是正则表达式中的模式字符串;参数string为要被分割的字符串;参数maxsplit是分隔次数,maxsplit=1表示分隔一次,默认为0,不限制次数;参数flags用于控制正则表达式的匹配方式,如是否区分大小写、多行匹配等。

【例5.9】使用正则表达式输出被标星的好友(源代码\ch05\5.9.py)。

    import re
    s1 = "*张三丰*李一真*陶渊明*李白"
    pattern = r'\*'
    ls= re.split(pattern,s1)           #以*分隔字符串
    print ("您的标星好友是:")
    for im in ls:
       if im != " ":                   #输出不为空的元素
           print(im)                   #输出每个好友时,去掉*符号

程序运行结果如图5-9所示。

图5-9 例5.9的程序运行结果