python3 爬虫相关学习10:RE 库/ regex /regular experssion正则表达式学习

news/2024/7/19 9:11:33 标签: 正则表达式, 爬虫, 学习

目录

1 关于:re / regex / regular expression 

1.1 什么是正则表达式

1.2 在python中安装正则模块  

1.2.1 python里一般都默认安装了 re正则模块,可以先查看确认下

1.2.2 如果没有安装,可以按照正则库regex, pip install regex 

1.3 在python中导入 re :  import re

正则表达式的相关符号

2.1 行定位符

2.2 元字符 (注意是 反斜杠\)

2.3 量词 \次数 \限定符号 : * + ? {}

2.4 字符类/字符集合: 中括号 [ ]

2.5 排除字符   [^ ]

2.6 选择字符 |

2.7 转义字符 反斜杠 \

2.8 分组符号  ()

2.9 正则表达式需要用引号"" 包裹起来

2.9.1 如果有特殊符号,表达式前还要注意加 r

2.9.2 无论是正则字符串,还是目标字符串,都记得要加 r

2.10 贪婪模式 / 非贪婪模式

正则表达式的方法

3.1 匹配和查找相关

3.2 相同点和差别

3.2.1 返回正则对象

3.2.2 不同的查找方法

3.2.3 不同的查找方法

3.2.4 不同的分割方法

3.3 re.match()

3.3.1 re 里大多数人接触第一个方法

3.3.2 MatchObject 对象的属性/方法

3.3.3 re.match()  和  ^  其实有点意义重复

3.3.4 使用 re.match() 来测试,数量的不同写法(可以等价)

3.3.5 所以一般返回  re.match() 即可,而不直接返回 re.match().group() ,原因就很明显了

3.3.6 测试正则 re.match()

3.4 re.search()

3.5 Flags标志

3.6  没有 re.find()  ,只有 re.findall()

3.7  re.findall()

3.8 re.sub()

3.9 re.finditer

3.10 re.compile()

3.11  re.split()


1 关于:re / regex / regular expression 

1.1 什么是正则表达式

  1. re 
  2. regex
  3.  regular expression
  • 正则表达式是计算机科学的一个概念
  • 是一个跨多种编程语言的语言格式,不同的语言里应该都有对应的正则库,而正则的规则是基本相同的。(我猜的  ^ ^ )

1.2 在python中安装正则模块  

1.2.1 python里一般都默认安装了 re正则模块,可以先查看确认下

  • 查看 regex模块
  • pip list
  • pip show regex

1.2.2 如果没有安装,可以按照正则库regex, pip install regex 

  • 导入 re 模块 
  • 错误写法: pip install  re
  • 正确写法:   pip install  regex

1.3 在python中导入 re :  import re

  • 导入 re 模块 
  • 模块其实可以认为是一个  .py文件
  • 正确写法:    import re

正则表达式的相关符号


2.1 行定位符

用来描述字符串的边界,1行的边界?全部字符串的边界把? 可以叫做 字符串整体定位符?^ ^

^       #表示字符串开头

$      #表示字符串结尾

2.2 元字符 (注意是 反斜杠\)

\w   #匹配 字母,数字,下划线等,还有各自文字,比如汉字

\W   #^w 非w

\s     # 匹配空格,换行,tab 等几种看不见的内容 也就是:空格 \n  \t

\S    #^s 非s

\b    #begin 单词的开始的意思  如 \bw 匹配单词(不是整个字符串)开始的字母,数字,下划线等,所以  \b不同于 ^

\B   #匹配非单词边界,即若某字串出现的单词字串未以空格分割,则不能匹配 ?

\d     # 匹配数字

.      #  任意字符

三种括号也是有特殊意义的

()    #匹配方括号的每个字符,比如(fruit|food)s 表示 fruits|foods

[]    # 匹配方括号的任一个字符,比如 [abc] 表示 a,b ,c 都可以

{}   # 限定次数符号,看下面

2.3 量词 \次数 \限定符号 : * + ? {}

量词,缺省值

  • 如果没有量词,默认就是1个
  • \d        # 比如\d匹配数字的;量词不写,默认就是1个的意思

其他量词限定

*         # 匹配前面的字符0次/无限次

+        # 匹配前面的字符1次/无限次   

?        # 匹配前面的字符0次/1次

  1.   但是这里有点注意,?表示量词时是0|1个,
  2.   常用于 .*? 这种非贪婪模式
  3.  但是放在其他量词后面表示,非贪婪匹配的意思,尽可能少的匹配

{n}      # 匹配前面的字符n次

{n,}     # 匹配前面的字符至少n次

{n,m}  # 匹配前面的字符 最少n次,最多m次, n-m次之间的都符合

e.g

^/d{8}     #匹配8个数字

.*s          #非贪婪匹配任意个数字

2.4 字符类/字符集合: 中括号 [ ]

[abcd]                      # 匹配abcd中的任意一个都可以

[12345]                    # 匹配1-5中的任意一个都可以

[0-9]                         # 匹配任意一个数字,等同于\d

[a-z0-9A-Z]              # 匹配所有英文字母,数字,几乎等同\w 是\w的子集(不含汉字等)

2.5 排除字符   [^ ]

关键字 ^

/W                   # 相当于/^w,但是写法不对,必须写在中括号里 [^]  写在外面还是表示字符串开始

[^a-zA-Z]         # 相当于非英文字母以外的其他任意字符

2.6 选择字符 |

选择

条件选择   | 表示or的意思

e.g.

^\d{5}|^\d{6}

2.7 转义字符 反斜杠 \

  • 转义字符
  1. 把 普通字符变成特殊意义的字符, n 转成 \n 换行符
  2. 把 特殊字符变成普通字符,   \* 表示 普通字符 *    \. 表示 普通字符 .

2.8 分组符号  ()

(fruit|food)s                 #表示 fruits|foods

([abc]{1,3}){3}             #表示 [abc]1到3个,然后再来3个,一会试试

2.9 正则表达式需要用引号"" 包裹起来

2.9.1 如果有特殊符号,表达式前还要注意加 r

  • 比如一般的
  • ".*?"
  • 实际使用时, 如果包含特殊符号,记得使用 r (rawdata)
  • r"https://movie.douban.com/apex"

2.9.2 无论是正则字符串,还是目标字符串,都记得要加 r

  • 正则字符串
  • 目标字符串,
  • 都可以加r 表示 不要转义,取原始字符串的意思

2.10 贪婪模式 / 非贪婪模式

贪婪模式

匹配符合条件的最多的字符数

非贪婪模式

匹配符合条件的最少的字符数

非贪婪匹配,如果一直到末尾,往往会匹配一个尽量少的字符串=none 空字符串 

?表示量词时是0|1个,但是放在其他量词后面表示,非贪婪匹配的意思,尽可能少的匹配

  • .*?       
  • *?
  • ??
  • +?
  • {n,m}?

例子1:

#E:\work\FangCloudV2\personal_space\2learn\python3\py0005.txt
# re相关

import re
print(re.match(r"aa\d+","aa2323"))   #会尽可能多的去匹配\d
print(re.match(r"aa\d+?","aa2323"))  #尽可能少的去匹配\d

例子2

#E:\work\FangCloudV2\personal_space\2learn\python3\py0005.txt
# re相关

import re

get1 = re.match(r'1[35678]\d{9}','13111111111')
print (get1)

get1 = re.match(r'1[35678]\d{9}','121111111111')
print (get1)

get1 = re.match(r'1[35678]\d{2}','13111111111')
print (get1)

get1 = re.match(r'1[35678]','13111111111')
print (get1)

get1 = re.match(r'1[35678]?','13111111111')
print (get1)

get1 = re.match(r'1[35678]\d{1,9}','13111111111')
print (get1)

get1 = re.match(r'1[35678]\d{1,9}?','13111111111')
print (get1)

正则表达式的方法

3.1 匹配和查找相关

  • re.match()
  • re.search()
  • re.findall()
  • re.finditer()
  • re.sub()
  • re.compile()
  • re.split()


3.2 相同点和差别

3.2.1 返回正则对象

  • re.compile()   # 返回一个正则对象
  • 其他的方法都返回, MatchObject 对象
  • 要么返回列表,可迭代对象

3.2.2 不同的查找方法

  • re.match()          #从开头查找
  • re.search()
  • re.findall()           # 返回一个列表
  • re.finditer()         # 返回可迭代对象

3.2.3 不同的查找方法

  • re.sub()          #替换

3.2.4 不同的分割方法

  • re.split()          #分割,返回列表对象

3.3 re.match()

3.3.1 re 里大多数人接触第一个方法

  • 语法
  • re.match(pattern,  string , flags=0)
  • 必须从字符串开头开始匹配
  • 返回一个对象 ! (包括none)
  • 返回 : MatchObject 对象,如果找不到则返回none
  1. none
  2. <re.Match object; span=(0, 1), match='1'>

3.3.2 MatchObject 对象的属性/方法

因为 re.match()返回的是一个MatchObject 对象,所以他有些特殊的属性

  • re.match()                 
  • # 使用正则对目标字符串,匹配后的内容
  • 返回的内容,<re.Match object; span=(0, 1), match='1'>
  • 类型:Match object;
  • span=(0,1) ,而其实就是 span=(start,end)
  • match="1" ,   其实就是返回匹配后的字符串 "1" 也就是 re.match.group()

  • re.match().span()        #  返回的是 使用正则对目标字符串匹配后的内容的字符串长度
  • re.match().start()         #  返回的是 使用正则对目标字符串匹配后的内容的字符串的开始位
  • re.match().end()         #  返回的是 使用正则对目标字符串匹配后的内容的字符串的结束位
  • re.match().string()       #  返回的是  要使用正则去匹配的 目标字符串
  • re.match().group()       #  返回的是  使用正则对目标字符串匹配后的内容--这个字符串str
#E:\work\FangCloudV2\personal_space\2learn\python3\py0005.txt
# re相关

import re

str1=re.match("^\d","123abc456ABC")
print (str1)
print (type(str1))
print (str1.start())
print (str1.end())
print (str1.span())
print (str1.string)
print (str1.group())
print (type(str1.group()))

3.3.3 re.match()  和  ^  其实有点意义重复

  • 用 re.match() 还需要加  ^ ?不需要,都表示从头开始查找了
  • 实测也如此
#E:\work\FangCloudV2\personal_space\2learn\python3\py0005.txt
# re相关

import re

print ("#第1次测试")
str1=re.match("^\d","123abc456ABC")
print (str1.group())
str1=re.match("^\d{1}","123abc456ABC")
print (str1.group())
str1=re.match("^\d{1,}?","123abc456ABC")
print (str1.group())
str1=re.match("^\d?","123abc456ABC")
print (str1.group())

print ("#第2次测试")
str2=re.match("\d","123abc456ABC")
print (str2.group())
str2=re.match("\d{1}","123abc456ABC")
print (str2.group())
str2=re.match("\d{1,}?","123abc456ABC")
print (str2.group())
str2=re.match("\d?","123abc456ABC")
print (str2.group())

3.3.4 使用 re.match() 来测试,数量的不同写法(可以等价)

比如我只用match()匹配字符串开头的一个数字

以下写法是等价的

  • \d               #会查找至少1个数字,0个会报错
  • \d{1}          #会查找至少1个数字,0个会报错
  • \d{1,}?       #会查找至少1个数字,0个会报错
  • 但是这里有点注意,?表示量词时是0|1个,但是放在其他量词后面表示,非贪婪匹配的意思,尽可能少的匹配

下面2个和上面的略有差别

  • \d?                #如果是0个也可以,返回none ,因为? 本身代表0 或者1
  • \d{0,}             # 如果是0个也可以,返回none

#E:\work\FangCloudV2\personal_space\2learn\python3\py0005.txt
# re相关

import re

print ("#第1次测试")
str1=re.match("^\d","123abc456ABC")
print (str1.group())
str1=re.match("^\d{1}","123abc456ABC")
print (str1.group())
str1=re.match("^\d{1,}?","123abc456ABC")
print (str1.group())
str1=re.match("^\d?","123abc456ABC")
print (str1.group())

print ("#第2次测试")
str2=re.match("\d","123abc456ABC")
print (str2.group())
str2=re.match("\d{1}","123abc456ABC")
print (str2.group())
str2=re.match("\d{1,}?","123abc456ABC")
print (str2.group())
str2=re.match("\d?","123abc456ABC")
print (str2.group())

print ("#第3次测试")
"""
#这几个找不到会报错
str3=re.match("\d","abc456ABC")
print (str3.group())
str3=re.match("\d{1}","abc456ABC")
print (str3.group())
str3=re.match("\d{1,}?","abc456ABC")
print (str3.group())
"""
str3=re.match("\d?","abc456ABC")
print (str3.group())
str3=re.match("\d{0,}","abc456ABC")
print (str3.group())

3.3.5 所以一般返回  re.match() 即可,而不直接返回 re.match().group() ,原因就很明显了

  • re.match()                            # 返回MatchObject 对象,有可能是<> 有可能是none
  • re.match().group()               #当MatchObject 对象是none时,这里会报错
  • re.match().group()               # 如果想这么写,一定考虑好错误处理,当MatchObject为none时做好处理

3.3.6 测试正则 re.match()

  • 可以用 
  • try:
  • except Exception as e:
  • 暂时先不处理错误而抛出异常!
  • Exception 要大写首字母
#E:\work\FangCloudV2\personal_space\2learn\python3\py0004.txt
# re相关

import re
i=1

def print_str(strA):
    global i
    print ("第%s次试验" %i)
    i=i+1
    try:
        print (strA)
        print ("")
    except Exception as e:
        print ("此次有报错",e)
        print ("")

print ("#测试身份证号")

#低级错误,半个括号)     \d而不是d

str1=re.match("^[0-9]{18}","110102198001017032")
print_str(str1)

str1=re.match("^\d{18}","110102198001017032")
print_str(str1)

str1=re.match("\d{17}(\d|[x])","110102198001017032")
print_str(str1)

str1=re.match("\d{17}(\d?|[x]?)","110102198001017032")
print_str(str1)

str1=re.match("\d{17}\d?","110102198001017032")
print_str(str1)


str1=re.match("^[1-9]\d{16}(\d|[x])","110102198001017032")
print_str(str1)

str1=re.match("^[1-9]\d{16}([0-9]|[x])","110102198001017032")
print_str(str1)

3.4 re.search()

  • 语法
  • ​search(pattern, string, flags=0)
  • 可以从字符串的任何地方开始查找匹配
  • 除了不从 目标字符串开头开始查找,其他和 re.match() 基本一致
  • 返回一个对象 ! (包括none)

3.5 Flags标志


在re库中,有一种Flags标志,它可以调整匹配的行为。常用的Flags标志有:

  • re.I:忽略大小写匹配
  • re.L:做本地化识别(locale-aware)匹配
  • re.M:多行匹配,影响 ^ 和 $ 标志
  • re.S:使 . 匹配包括换行符在内的所有字符
  • re.U:根据Unicode字符集解析字符。这个标志会影响 \w, \W, \b, \B
  • re.X:为了增加可读性,忽略空白符号的意义并允许你把横跨多行的正则表达式写成"非括号化"的形式

3.6  没有 re.find()  ,只有 re.findall()

  • 居然没有 re.find()
  • 使用此方法会报错!

3.7  re.findall()

  • 语法
  • findall(pattern, string, flags=0)
  • 返回一个 列表\
  • 比如下面的
  • re.findall("",str)
  • re.findall("",str,re.I)

3.8 re.sub()

  • 语法
  • sub(pattern, repl, string, count=0, flags=0)
  • 在string内部,按正则 pattern 去替换 repl ,数量为 count 次

  • 如果不指定数量,默认只替换1次
  • 如果指定数量,则替换对应次数
  • 但是默认不能识别大小写,需要有参数 re.I 才可以

3.9 re.finditer

  • 语法
  • re.finditer(pattern, string[, flags=0])
  • 返回,一个可迭代对象
  • <callable_iterator object at 0x00000282083B4D90>
  • 虽然直接看不懂
  • 但是可以用循环,取出其中内容

3.10 re.compile()

  • 编译正则表达式
  • compile(pattern, flags=0)
  • re.compile() 和前面的 re的各种方法不同,他不是一个方法,而是生成一个正则规则,然后其他正则方法,re.search()  re.match() 等使用这个正则去匹配、
  • 但是,暂时和直接 用正则规则写一个"" 字符串的正则规则,比较 compile() 生成的有什么区别,暂时不知道,留着待查

#E:\work\FangCloudV2\personal_space\2learn\python3\py0005.txt
# re相关

import re


str1="abcabcabcABC"
str_pattern=re.compile("a.*?c")
re_content=str_pattern.match(str1)
print(re_content.group())

str1="abcabcabcABC"
get1=re.search("a.*?c",str1)
print(get1.group())

3.11  re.split()

  • 分隔
  • 语法
  • split(pattern, string, maxsplit=0, flags=0)
  • 按 pattern 去分割 string,
  • maxsplit=0, 默认次数为0,即无限次!!!
  • 并且返回一个列表!


http://www.niftyadmin.cn/n/447664.html

相关文章

从零使用source insight并完成必要设置

文章目录 1 创建新工程2 打开四大窗口3 更改编码方式5 修改背景颜色为护眼色6 设置批量注释和批量取消注释7 选择变量高亮其他相同变量也高亮8 自定义快捷键 1 创建新工程 点new project&#xff0c;改成自己熟悉的名字 选择源文件路径 add tree 加载完成后点close 然后点Pr…

CSS查缺补漏之《如何优雅解决margin垂直方向塌陷与合并问题?》

一&#xff1a;父子元素之间margin垂直方向塌陷问题 在处理margin垂直方向问题时&#xff0c;经常会遇到在给子元素设置margin时&#xff0c;导致效果出现在了父元素上&#xff1b;如下代码所示&#xff1a; 代码原义是想实现三方面&#xff1a; ① 将box1的margin-top调为5…

6月17日每日两题

第一题&#xff1a;HackSon的趣味题 Hanks 博士是BT (Bio-Tech&#xff0c;生物技术) 领域的知名专家&#xff0c;他的儿子名叫Hankson。现在&#xff0c;刚刚放学回家的Hankson 正在思考一个有趣的问题。 今天在课堂上&#xff0c;老师讲解了如何求两个正整数c1 和c2 的最大公…

java项目之汉服文化平台网站(ssm+vue)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的汉服文化平台网站。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 &#x1f495;&#x1f495;作者&#xff1a;风歌&…

短视频账号矩阵系统sign解密流程(开发)

PHP加密后直接用这个PHP解码如何解密&#xff1f; IOC 控制反转 把创建对象过程交给spring进行管理&#xff0c;降低耦合度 底层原理 xml解析、工厂模式、反射 过程&#xff1a; 使用xml创建对象 使用xml解析技术解析 通过反射创建对象 Class clazz Class.forName(解析出来…

管理类联考——写作——技巧篇——论证有效性——谬误概念汇总简释

批判性思维常见逻辑谬误 有些错误出现在我们澄清或定义某个观点的时候&#xff0c;有些错误出现在我们收集证据或者用证据和理由支撑某个观点的时候&#xff0c;有些错误出现在我们尝试从证据得出结论的时候&#xff0c;有些错误甚至出现在我们评估他人的观点或者理由的时候。…

【深度学习】3-1 神经网络的学习- 学习基础/损失函数

学习基础 神经网络的学习。这里所说的“学习”是指从训练数据中自动获取最优权重参数的过程。 神经网络的特征就是可以从数据中学习。所谓“从数据中学习”&#xff0c;是指可以由数据自动决定权重参数的值。 数据驱动 数据是机器学习的命根子。从数据中寻找答案、从数据中发…

【Vue3+Ts project】认识 @vueuse/core 库

目标: 根据屏幕宽度改变 实现动态获取盒子的宽度 目录 目标: 一、javascript实现 二、vueuse/core 库实现 一、javascript实现 1.首先 window.innerWidth 获取当前屏幕宽度&#xff0c;然后将 盒子宽度 除 375 乘 当前屏幕宽度 150 / 375 * window.innerWidth 2.将获取的…