山东大学Python(7)——正则

#%%
# 使用 jupyter notebook 编写
"""
本章知识目录:
    1.正则表达式简介
    2.正则表达式常用操作符
    3.字符
    4.pattern类
    5.re模块
"""

"""
考试:
正则表达式语法、常用操作符(都要掌握)
经典正则表达式方法的实例
search的使用
findall的使用
match的使用
其他也要看,重点是上面的3个(多练)
"""

#%%

"""
正则表达式简介:
    正则表达式(regular expression),又记作re或regex
    是用来简洁表达一组字符串的表达式
    正则表达式是独立于语言存在的,不同语言有不同的实现方式
    Python:内置模块re

正则表达式常用操作符:
    (1) . 可以匹配任意单个字符(除换行符) 
    (2) \ 表示转义字符 \t \n \r \f \v \- \[ \] \^
    (3) [ ] 能匹配单个任意集合中的字符,例:[a-zA-Z0-9]能匹配任意大小写字母和数字
    (4) [^ ] 可以匹配出单个集合元素之外的所有字符,‘^’表示除去字符 
    (5) | 表示有个特定的模式,如‘python|perl’只匹配python和perl 
    (6) (pattern)? 允许模式重复0次或1次
    (7) (pattern)* 允许模式重复0次或多次,abc*表示abc、abcc、abccc
    (8) (pattern)+ 允许模式重复1次或多次
    (9) (pattern){m} 允许模式重复m次 
    (10) (pattern){m, n} 允许模式重复m到n次,包含n 
    (11) ^ 行首匹配,匹配一行字符串开头,^abc表示abc且在一个字符串的开头(换行符结束)
    (12) $ 行尾匹配,匹配一行字符串结尾,abc$表示abc且在一个字符串的开头(换行符结束)
    (13)( ) 分组标记,组内只能使用 | 操作符
    (14)\d 匹配一个数字, 相当于 [0-9] 
    (15)\D 匹配非数字,相当于 [^0-9] 
    (16)\s 匹配任意空白字符, 相当于 [\t\n\r\f\v] 
    (17)\S 匹配非空白字符,相当于 [^\t\n\r\f\v] 
    (18)\w 匹配数字、字母、下划线中任意一个字符, 相当于 [a-zA-Z0-9_] 
    (19)\W 匹配非数字、字母、下划线中的任意字符,相当于 [^a-zA-Z0-9_]
    (20)\A 匹配整个匹配串的开头(包括换行符)
    (21)\Z 匹配整个匹配串的结尾(包括换行符)
    
字符:
    1.原生字符串
        原生字符串(raw string)是 Python 里一种写字符串的形式
        比如:R’abcdefg’ 或 r’C:\courses\python\progs’
        R’C:\courses\python\progs’的等价写法是’C:\\courses\\python\\progs’’
    2.元字符
         re 规定了一组特殊字符,称为元字符,它们在匹配字符串时起着特殊的作用。
        这种字符一共 14 个:. ^ $ * + ? \ | { } [ ] ( )
    3.比较
        原始字符串中,所有字符表达原来的内容
        普通字符串中,只有少量如 \ 的转义字符代表特殊内容,别的字符表达原来的内容
        正则表达式中,上述所有特殊字符都代表特殊内容
        表示能力:正则表达式 > 普通字符串 > 原始字符串

pattern类:
    Python的正则表达式包re中,最基本的类就是 pattern
    正则表达式的对象可以从普通的字符串生成,语句为:
			r1 = re.compile(普通字符串) 
"""
import re
str1 = 'I love you, qyz!'
str2 = '34dfaasdfadfad'
reverseName = re.compile('^I.*[u]')
t = re.findall(reverseName, str1)
print(t)
t = re.findall('^I.*[u]', str1)
print(t)
pattern2 = re.compile('^adf$')
t = pattern2.findall(str2)
print(t)

#%%

"""
re模块:
    1.两种等价形式
    事实上,使用上述几个函数的方式有两种——将其作为一般的函数,
    或者将其作为正则表达式对象的方法。
    例如使用search函数的时候,我们有两种等价的方式:
    re.search(pattern,字符串)#直接把普通字符串pattern当正则表达式语使用
    
    r1=re.compile(pattern)#先用pattern生成正则表达式对象r1
    r1.search(字符串)
    这两种写法是等价的。如果只需要使用一次正则表达式,可以用第一种写法,
    以节省时间。如果要多次使用,不妨先将r1生成一个正则表达式以便多次复用。
    2.re模块中的函数
        search
        findall
        finditer
        match
        fullmatch
        split
        sub
        subn
        pattern
    3.re模块的规则都是贪婪匹配的,这点很重要
    贪婪匹配的含义不是要找出'最多'的匹配,
    而是要在每一次匹配的时候找到'最大'的匹配。
    这提醒我们,一定要当心使用*,最好都改为由限定范围的{:n}

"""

#%%

"""
search
    用法是re.search(pattern,字符串)
    对字符串进行模式搜索,如果找到第一个匹配的位置,返回一个MatchObject对象;
    这个对象中储存了匹配位置、匹配内容等信息。
    若该字符串没有模式匹配,则返回None。
    例如:手机评论数据中出现很多的关于屏幕、音频、拍照之类的功能评价,
    那么在实际数据分析中,我们可能需要看评论中是否会出现'屏幕'。
    re.search()函数便是根据需要匹配的模式进行搜索的函数
"""
import re
comment = "这个手机很好,屏幕的质量很好"
pattern = "屏幕.*[好坏]"
re.search(pattern, comment)
# search进行的是贪婪匹配,即寻找最大的匹配,为避免错误可以将*换成{:n},限制间隔字数
# 贪婪指的是匹配的最大,而不是最多。
# search只是寻找从左到右第一个与正则表达式匹配,而不是找到所有匹配位置。

#%%

"""
findall
    findall函数可以找出所有匹配,并把它们从左到右作为一个列表返回。
    如果无匹配,返回空列表。
"""
import re
comment = "屏幕很好?开玩笑吧!明明屏幕很坏!"
pattern = "屏幕.[好坏]"
#pattern = re.compile("屏幕.[好坏]") # 这样也可以 
re.findall(pattern, comment)

#%%

"""
finditer
    1.finditer函数与findall函数的作用基本是一样的。
    不同的是finall返回的是一个列表,finditer返回的是一个迭代器。
    迭代器用完之后可以自动释放内存。
    2.在处理的数据较大的时候,finditer或许会发挥其作用。
    但如果数据较小、不重视内存,或者手动释放,
    则finditer的功能可以完全被findall取代。
"""
import re


#%%

"""
match
    1.用法是re.match(pattern,字符串),和re.search()类似,
    唯一不同的是re.match()只从头开始匹配,re.search()可以匹配任一位置的字符串。
    2.即如果符合正则表达式的字符串如果出现在开头,
    那么使用re.match()后会返回MatchObject对象,
    但如果出现在中间位置或没有,则返回None。
    3.也可以等价于在search函数的pattern前增加一个表示字符串开头的'\A'字符
    4.Match函数也是贪婪的。并且,它显然不存在匹配第一个还是多个这样的
"""
import re
str = """first line
second line
third line
"""
pattern = "\w+"
re.match(pattern, str)

#%%

"""
fullmatch
    1.用法和match类似,但它不但是'从头匹配',而是'从头到尾'匹配
    2.可以说,fullmatch就是用来检测pattern与整个string是不是匹配的
"""
import re
str1 = "abcd1234"
str2 = "abcd1234k"
pattern = "[a-z]*[0-9]*"
print(re.fullmatch(pattern, str1))
print(re.fullmatch(pattern, str2))

#%%

"""
split
    1.一般的字符串也有split函数,用法是string.split(sep=分隔符)
    则得到一个将字符串按照分隔符划分而成的列表
    但是只能用一种字符串做为sep来进行切分,功能不够强大
    以下是str字符串的一些方法:
        split 分割 
        strip返回去除两侧空格的字符串 
        默认删除空白符包括‘\n’ ‘\t’ ‘\r ’ ‘ ’ 
        lstrip删除开头空白 
        rstrip删除末尾空白 
        join 添加 与split方法相反
    2.使用re.split(pattern,string)
    可以将string中所有与pattern匹配的东西做为分割符,继而将字符串分割为一列表
    3.split函数还可以指定maxsplit参数,规定最大被划分多少次
    若maxsplit=a,则最大划分3次,最多分成4份
"""
string = "1,2,3,4,5,6"
lst = string.split(sep=',')
print(lst)
import re
string = "You 12are 99so 86beautiful"
pattern = "\s+\d+"
lst = re.split(pattern, string)
print(lst)
lst = re.split(pattern, string, maxsplit=2)
print(lst)

#%%

"""
sub 
    1.re.sub(pattern,repl,字符串)方法用于对符合正则表达式字符串的替换。
    2.像是前面'触摸屏'、'屏幕'可认为是同义词的情况,是可以进行词替换的,这样可以减少进入训练模型的特征维度。
    3.可以指定一个count的参数,限制最大的匹配替换次数。
"""
import re
comment = "广告说这个触摸屏很好,推销的人也说这个屏幕很好,但我觉得这个显示屏糟透了"
pattern = "(触摸屏)|(显示屏)"
print(re.sub(pattern, "屏幕", comment))
print(re.sub(pattern, "ppp", comment, count=1))

#%%

"""
subn
    subn与sub的使用方式与结果介乎是一样的,
    不同的是,subn返回的对象是一个被替换后的字符串与替换次数的两元组
"""
import re
comment = "广告说这个触摸屏很好,推销的人也说这个屏幕很好,但我觉得这个显示屏糟透了"
pattern = "(触摸屏)|(显示屏)"
print(re.subn(pattern, "屏幕", comment))
print(re.subn(pattern, "ppp", comment, count=1))

发布了36 篇原创文章 · 获赞 20 · 访问量 2923

猜你喜欢

转载自blog.csdn.net/weixin_43360801/article/details/103318056