0%

python012

使用正则表达式

在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要,正则表达式就是用于描述这些规则的工具,换句话说正则表达式是一种工具,它定义了字符串的匹配模式(如何检查一个字符串是否有跟某种模式匹配的部分或者从一个字符串中将与模式匹配的部分提取出来或者替换掉)。Python通过标准库中的re模块来支持正则表达式操作。

符号 解释 示例 说明
. 匹配任意字符 b.t 可以匹配到bat/but/b@t/等
\w 匹配字母/数字/下划线 b\w bat/b1t/b_t,不能匹配b#t
\s 匹配空白字符包括\r \n \t等 love\syou love you
\d 匹配数字 \d\d 可以匹配到01/23/99等
\b 匹配单词的边界 \bThe\b
^ 匹配字符串的开始 ^The 可以匹配The开头的字符串
$ 匹配字符串的结束 .exe$ 匹配到.exe结尾的字符串
\W 匹配非字母/数字/下划线 b\Wt 可以匹配到b#t b@t等,不能but b1t b_t
\S 匹配非空白字符 love\Syou love@you 不能匹配到love you
\D 匹配非数字 \d\D 9a 3#
\B 匹配非单词边界 \Bio\B
[] 匹配来自字符集的任意单一字符 [aeiou] 可以匹配任一元音字母
[^] 匹配不在字符集中的任意单一字符 [^aeiou] 可以匹配任一非元音字母
* 匹配0次或多次 \w*
+ 匹配一次或多次 \w+
? 匹配0次或1次 \w?
{N} 匹配N次 \w{3}
{M,} 匹配至少M次 \w{3,}
{M,N} 匹配至少M次至多N次 \w{3,6}
| 分支 foo|bar 可以匹配foo或者bar
(?#) 注释
(exp) 匹配exp并捕获到自动命名的组中
(?exp) 匹配exp并捕获到名未name的组中
(?:exp) 匹配exp但是不捕获匹配的文本
(?=exp) 匹配exp前面的位置 \b\w+(?=ing) I’m dancing中的danc
(?<=exp) 匹配exp后面的位置 (?<=\bdanc)\w+\b I love dancing and reading中的第一个ing
(?!exp) 匹配后面不是exp的位置
(?<!exp) 匹配前面不是exp的位置
*? 重复任意次,但尽肯能少重复 a.*b a.*?b 在aabab中,前者aab,后者ab
+? 重复一次或者多次,但是尽可能少重复
?? 重复0次或者1次,但尽可能少重复
{M,N}? 重复M到N次,但尽可能少重复
{M,}? 重复M次以上,但尽可能少重复
如果匹配正则表达式中的特殊字符,加转义字符就可以了

Python对正则表达式的支持 import re,re模块中核心函数

函数 说明
complie(pattern, flags=0) 编译正则表达式返回正则表达式对象
match(pattern,string,flags=0) 用正则表达式匹配字符串 成功返回匹配对象,不成功返回None
search(pattern,string,flags=0) 搜索字符串中第一次出现正则表达式的模式,成功返回匹配对此,否则None
split(pattern,string,maxsplit=0,flags=0) 用正则表达式指定的模式分隔符拆分字符串 返回列表
sub(patter, repl,string,count=0,flags=0) 用指定的字符串替换原字符串中与正则表达式匹配的模式,可以利用count指定替换掉的次数
fullmatch(pattern,string,flags=0) 用match函数的完全匹配(从字符串开头到结尾)版本
findall(pattern,string,flags=0) 查找字符串所有与正则表达式匹配的模式,返回字符串的列表
finditer(pattern,string,flags=0) 查找字符串所有与正则表达式匹配的模式,返回一个迭代器
purge() 清除隐式编译的正则表达式的缓存
re.I/re.IGNORECASE 忽略大小写匹配标记
re.M/re.MULTILINE 多行匹配标记

说明: 上面提到的re模块中的这些函数,实际开发中也可以用正则表达式对象的方法替代对这些函数的使用,如果一个正则表达式需要重复的使用,那么先通过compile函数编译正则表达式并创建出正则表达式对象无疑是更为明智的选择。

1.验证输入的用户名和QQ号是否有效并给出对应的提示信息

'''
验证输入用户名和QQ号是否有效并给出对应的提示信息
要求:用户名必须由字母数字下划线构成且长度在6--20个字符之间
QQ号是5--12的数字且首位不能为0
'''
import re


def main():
    username = input("请输入用户名:")
    qq = input("请输入qq号:")
    # match函数的第一个参数时正则表达式字符串或正则表达式对象
    # 第二个参数是要跟正则表达式做匹配的字符串对象
    m1 = re.match(r'^[0-9a-zA-Z_]{6,20}$', username) 
    if not m1:
        print("请输入有效的用户名")
    m2 = re.match(r'^[1-9]\d{4,11}$', qq)
    if not m2:
        print("请输入有效的qq号")
    if m1 and m2:
        print("你输入的信息是有效的")


if __name__ == "__main__":
    main()

2.从一段文字中提取出国内的手机号码

import re


def main():
    '''创建正则表达式对象,使用了前瞻和回顾来保证手机号前后不应该出现数字
    '''
    pattern = re.complie(r'(?<=\D)1[34578]\d{9}(?=\D)')
    sentence = '''
        重要的事情说8130123456789遍,我的手机号是13512346789这个靓号,不是15600998765,也是110或119,王大锤的手机号才是15600998765。
        '''
    # 查找所有匹配并保存到一个列表中
    mylist = re.findall(pattern, sentence)
    print(mylist)
    print("------华丽的分割线-----")
    # 通过迭代器取出匹配对象并获得匹配的内容
    for temp in pattern.finditer(sentence):
        print(temp.group())
    print("------华丽的分割线-----")
    # 通过search函数指定搜索位置找出所有匹配
    m = pattern.search(sentence)
    while m:
        print(m.group())
        m = pattern.search(sentence, m.end())


if __name__ == "__main__":
    main()

3.替换字符串中的不良内容

import re


def main():
    sentence = "你丫是个傻叉吧,我操你大爷的,Fuck you"
    purified = re.sub('[操肏艹]|fuck|shit|傻[比逼屄叉缺吊屌]|煞笔','*', sentence, flags=re.IGORECASE)
    print(purified)


if __name__ "__main__":
    main()

4.拆分字符串

import re


def main():
    poem = "窗前明月光,疑是地上霜。举头望明月,低头思故乡。"
    sentence_list = re.split(r'[,。, .]', poem)
    while '' in sentence_list:
        sentence_list.remove('')
    print(sentence_list)  # ['床前明月光', '疑是地上霜', '举头望明月', '低头思故乡']


if __name__ == "__main__":
    main()