python3.7正则表达式语法_python3 re模块与正则表达式

文章最后更新时间为:2019年07月12日 16:24:32

在python3爬虫(一)中,我总结了requests库的相关方法和一些使用举例,通过requests模块,我们可以获取网页的html或者其他形式的内容,但是这些内容太过于繁杂,所以我们要对这些内容进行处理和提取,比如如果我们想要下载网页中存在的图片,那我们需要找出所有内容中以.jpg或者.png等结尾的字符串并提取出来。

1、正则表达式

正则表达式就是一组可以匹配一类字符串的表达式。通过提取网页中与正则表达式相匹配的字符串,我们就可以获取想要的字符串,但是正则表达式的语法和语法规则是怎么样的呢?

(1)正则表达式匹配的格式

下表总结了正则表达式常用的规则:语法意义说明"."任意字符

"^"字符串开始'^hello'匹配'helloworld'而不匹配'aaaahellobbb'

"$"字符串结尾与上同理

"*"0 个或多个字符(贪婪匹配)<*>匹配

chinaunix

"+"1 个或多个字符(贪婪匹配)与上同理

"?"0 个或多个字符(贪婪匹配)与上同理

*?,+?,??以上三个取第一个匹配结果(非贪婪匹配)<*>匹配

{m,n}对于前一个字符重复m到n次,{m}亦可a{6}匹配6个a、a{2,4}匹配2到4个a

{m,n}?对于前一个字符重复m到n次,并取尽可能少‘aaaaaa'中a{2,4}只会匹配2个

"\"特殊字符转义或者特殊序列

[]表示一个字符集[0-9]、[a-z]、[A-Z]、

""或AB,或运算

(...)匹配括号中任意表达式

(?#...)注释,可忽略

(?=...)Matches if ... matches next, but doesn't consume the string.'(?=test)' 在hellotest中匹配hello

(?!...)Matches if ... doesn't match next.'(?!=test)' 若hello后面不为test,匹配hello

(?<=...)Matches if preceded by ... (must be fixed length).'(?<=hello)test' 在hellotest中匹配test

(?

正则表达式特殊序列表符号意义\A只在字符串开始进行匹配

\Z只在字符串结尾进行匹配

\b匹配位于开始或结尾的空字符串

\B匹配不位于开始或结尾的空字符串

\d相当于[0-9]

\D相当于[^0-9]

\s匹配任意空白字符:[\t\n\r\r\v]

\S匹配任意非空白字符:[^\t\n\r\r\v]

\w匹配任意数字和字母:[a-zA-Z0-9]

\W匹配任意非数字和字母:[^a-zA-Z0-9]

(2) 贪婪格式和非贪婪格式

1 概述:贪婪与非贪婪模式影响的是被量词修饰的子表达式的匹配行为,贪婪模式在整个表达式匹配成功的前提下,尽可能多的匹配,而非贪婪模式在整个表达式匹配成功的前提下,尽可能少的匹配。

属于贪婪模式的量词,也叫做匹配优先量词,包括:

“{m,n}”、“{m,}”、“?”、“*”和“+”。

在一些使用NFA引擎的语言中,在匹配优先量词后加上“?”,即变成属于非贪婪模式的量词,也叫做忽略优先量词,包括:

“{m,n}?”、“{m,}?”、“??”、“*?”和“+?”。

2 贪婪与非贪婪模式匹配原理

举例:源字符串:aa

test1
bb
test2
cc

正则表达式一:

.*

匹配结果一:

test1
bb
test2

正则表达式二:

.*?

匹配结果二:

test1
(这里指的是一次匹配结果,所以没包括
test2

仅从应用角度分析,可以这样认为,贪婪模式,就是在整个表达式匹配成功的前提下,尽可能多的匹配,也就是所谓的“贪婪”,通俗点讲,就是看到想要的,有多少就捡多少,除非再也没有想要的了.非贪婪模式,就是在整个表达式匹配成功的前提下,尽可能少的匹配,也就是所谓的“非贪婪”,通俗点讲,就是找到一个想要的捡起来就行了,至于还有没有没捡的就不管了。

3 前提条件

无论是贪婪模式还是非贪婪模式,都是在字符串成功匹配的前提下,字符串匹配不成功,贪婪模式和非贪婪模式都不会发挥作用。

例如下面的例子:正则表达式三:

.*
bb

匹配结果三:

test1
bb

正则表达式四:

.*?
cc

匹配结果四:

test1
bb
test2
cc

2、re模块

re模块提供了正则表达式匹配操作,要搜索的模式和字符串都可以是Unicode字符串(str)以及8位字符串(bytes)。但是,Unicode字符串和8位字符串不能混用:也就是说,不能将Unicode字符串与字节模式匹配,反之亦然; 类似地,当要求替换时,替换字符串必须与模式和搜索字符串的类型相同。

下面总结了re模块常用的方法

(1)re.compile(pattern,flags = 0 )

将一个正则表达式模式编译成一个正则表达式对象,可以用它进行匹配 match(),search()以及其他方法,如下所述。prog = re.compile(pattern)

result = prog.match(string)

相当于:result = re.match(pattern, string)

flags定义包括:re.I:忽略大小写

re.L:表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境

re.M:多行模式

re.S:' . '并且包括换行符在内的任意字符(注意:' . '不包括换行符)

re.U: 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库

所以re.compile()如果在单个程序中多次使用表达式,则使用并保存生成的正则表达式对象以便重用将会更有效。

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

扫描字符串查找正则表达式模式产生匹配的第一个位置 ,并返回相应的匹配对象。如果字符串中没有位置与模式匹配,则返回None.>>> re.search(r'[ab]',"aaaasdfg")

<_sre.SRE_Match object; span=(0, 1), match='a'>

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

如果字符串开头的零个或多个字符与正则表达式模式匹配,则返回相应的匹配对象。如果字符串不匹配模式,则返回None。>>> re.match("a", "abcdef")

<_sre.SRE_Match object; span=(0, 1), match='a'>

请注意,即使在MULTILINE模式下,re.match()只会匹配字符串的开头,而不是每行的开头。

search()与match()的区别

match()只匹配字符串的开头!

看例子:>>> re.match("c", "abcdef") # No match

>>> re.search("c", "abcdef") # Match

<_sre.SRE_Match object; span=(2, 3), match='c'>

以正值开始的正则表达式'^'可用于search()限制字符串开始处的匹配:>>> re.match("c", "abcdef") # No match

>>> re.search("^c", "abcdef") # No match

>>> re.search("^a", "abcdef") # Match

<_sre.SRE_Match object; span=(0, 1), match='a'>

但是请注意,在MULTILINE模式中,match()只匹配字符串的开头,而使用search()正则表达式'^'匹配每行的开头。>>> re.match('X', 'A\nB\nX', re.MULTILINE) # No match

>>> re.search('^X', 'A\nB\nX', re.MULTILINE) # Match

<_sre.SRE_Match object; span=(4, 5), match='X'>

match对象

匹配对象总是有一个布尔值True。由于match()与search()返回None 时没有匹配,我们可以测试是否有一个简单的匹配 if语句:match = re.search(pattern, string)

if match:

process(match)

匹配对象支持以下方法和属性:match.group([ group1,... ] )

match.groups(default=None)

match.groupdict(default=None)

match.start([group])

match.end([group])

match.span([group])

(4)re.findall(pattern,string,flags = 0 )

返回字符串中模式的所有非重叠匹配项,作为字符串列表。 字符串从左到右扫描,匹配按找到的顺序返回。 如果模式中存在一个或多个组,则返回组的列表; 如果该模式有多个组,这将是一个元组列表。>>> re.findall(r'a',"aboisdhiajhsasa")

['a', 'a', 'a', 'a']

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

由模式发生的分割字符串。如果在模式中使用捕获圆括号,则模式中所有组的文本也将作为结果列表的一部分返回。如果maxsplit不为零,则最多 发生maxsplit分割,并将其余的字符串作为列表的最后一个元素返回。

举例:>>> re.split('\W+', 'Words, words, words.')

['Words', 'words', 'words', '']

>>> re.split('(\W+)', 'Words, words, words.')

['Words', ', ', 'words', ', ', 'words', '.', '']

>>> re.split('\W+', 'Words, words, words.', 1)

['Words', 'words, words.']

>>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)

['0', '3', '9']

如果分隔符中存在捕获组,并且匹配字符串的开头,则结果将以空字符串开头。字符串的末尾也是一样:>>> re.split('(\W+)', '...words, words...')

['', '...', 'words', ', ', 'words', '...', '']

总结

re模块匹配字符串一般步骤:先将正则表达式的字符串形式编译为Pattern实例。

然后使用Pattern实例处理文本并获得匹配结果(一个Match实例)。

最后使用Match实例获得信息,进行其他的操作。

到这里我们就可以从一堆字符串中提取出我们想要的部分了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值