python之正则表达式

python基础

浏览数:164

2019-8-15

正则表达式

正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。

正则表达式是用来匹配字符串非常强大的工具,在其他编程语言中同样有正则表达式的概念,Python同样不例外,利用了正则表达式,我们想要从返回的页面内容提取出我们想要的内容就易如反掌了。

    正则表达式的大致匹配过程是:
    1.依次拿出表达式和文本中的字符比较,
    2.如果每一个字符都能匹配,则匹配成功;一旦有匹配不成功的字符则匹配失败。
    3.如果表达式中有量词或边界,这个过程会稍微有一些不同。

符号 说明 实例
. 表示任意字符,如果说指定了 DOTALL 的标识,就表示包括新行在内的所有字符。 ‘abc’  >>>’a.c’   >>>结果为:’abc’ 
^ 表示字符串开头。 ‘abc’  >>>’^abc’  >>>结果为:’abc’
$ 表示字符串结尾。 ‘abc’  >>>’abc$’  >>>结果为:’abc’
*, +, ? ‘*’表示匹配前一个字符重复 0 次到无限次,’+’表示匹配前一个字符重复 1次到无限次,’?’表示匹配前一个字符重复 0 次到1次

‘abcccd’  >>>’abc*’ >>>结果为:’abccc’

‘abcccd’ >>>’abc+’  >>>结果为:’abccc’

‘abcccd’ >>>’abc?’  >>>结果为:’abc’

*?, +?, ??    前面的*,+,?等都是贪婪匹配,也就是尽可能多匹配,后面加?号使其变成惰性匹配即非贪婪匹配

‘abc’  >>>’abc*?’ >>>结果为:’ab’

‘abc’  >>>’abc??’ >>>结果为:’ab’

‘abc’  >>>’abc+?’ >>>结果为:’abc’

{m} 匹配前一个字符 m 次 ‘abcccd’ >>>’abc{3}d’  >>>结果为:’abcccd’
{m,n} 匹配前一个字符 m 到 n 次 ‘abcccd’  >>> ‘abc{2,3}d’ >>>结果为:’abcccd’
{m,n}? 匹配前一个字符 m 到 n 次,并且取尽可能少的情况  ‘abccc’  >>> ‘abc{2,3}?’ >>>结果为:’abcc’
\ 对特殊字符进行转义,或者是指定特殊序列  ‘a.c’ >>>’a\.c’ >>> 结果为: ‘a.c’
[]                  表示一个字符集,所有特殊字符在其都失去特殊意义,只有: ^  –  ]  \   含有特殊含义 ‘abcd’ >>>’a[bc]’ >>>结果为:’ab’
| 或者,只匹配其中一个表达式 ,如果|没有被包括在()中,则它的范围是整个正则表达式 ‘abcd’ >>>’abc|acd’ >>>结果为:’abc’
( … ) 被括起来的表达式作为一个分组. findall 在有组的情况下只显示组的内容  ‘a123d’ >>>’a(123)d’ >>>结果为:’123′
(?#…) 注释,忽略括号内的内容  特殊构建不作为分组  ‘abc123′ >>>’abc(?#fasd)123′ >>>结果为:’abc123’
(?= … ) 表达式’…’之前的字符串,特殊构建不作为分组 在字符串’ pythonretest ’中 (?=test) 会匹配’ pythonre ’
(?!…) 后面不跟表达式’…’的字符串,特殊构建不作为分组 如果’ pythonre ’后面不是字符串’ test ’,那么 (?!test) 会匹配’ pythonre ’
(?<= … ) 跟在表达式’…’后面的字符串符合括号之后的正则表达式,特殊构建不作为分组 正则表达式’ (?<=abc)def ’会在’ abcdef ’中匹配’ def ’
(?:) 取消优先打印分组的内容 ‘abc’ >>>'(?:a)(b)’ >>>结果为'[b]’
?P<> 指定Key ‘abc’ >>>'(?P<n1>a)>>>结果为:groupdict{n1:a}

正则表达式特殊序列

特殊表达式序列 说明
\A 只在字符串开头进行匹配。
\b 匹配位于开头或者结尾的空字符串
\B 匹配不位于开头或者结尾的空字符串
\d 匹配任意十进制数,相当于 [0-9]
\D 匹配任意非数字字符,相当于 [^0-9]
\s 匹配任意空白字符,相当于 [ \t\n\r\f\v]
\S 匹配任意非空白字符,相当于 [^ \t\n\r\f\v]
\w 匹配任意数字和字母,相当于 [a-zA-Z0-9_]
\W 匹配任意非数字和字母的字符,相当于 [^a-zA-Z0-9_]
\Z 只在字符串结尾进行匹配
import re
#  . 通配符
print(re.findall("d..h","asdfghjkl"))
#  ^  以什么开头
print(re.findall("^dh","dhasdfghjkl"))
#  $  以什么结尾
print(re.findall("dh$","dhasdfghjkldh"))
#  *  [0,∞ ]
print(re.findall("dha*","dhasdfghjkldh"))
#  +  [1,∞ ]
print(re.findall("dh+","dhasdfghjkldh"))
#  ?  [0,1]
print(re.findall("ghx?","dhasdfghxxxx"))
#  {0,}==*  {1,}==+  {0,1}==?
print(re.findall("ghx{4}","dhasdfghxxxx")) #重复x 4次
print(re.findall("ghx{1,4}","dhasdfghxx")) #重复x 1到4次
#注意,前面的*,+,?等都是贪婪匹配,也就是尽可能的匹配,后面加?号使其变成惰性匹配
print(re.findall("ghx*?","dhasdfghxx")) #按最少的去匹配
print(re.findall("ghx+?","dhasdfghxx")) #按最少的去匹配
#----------------------------------------------------------------------------
#元字符之字符集[] 中口号中最少有一个,字符集中只有\,^,-是特殊符号
# []   相当于或
print(re.findall("g[hz]","dhghafgzxx"))
# -
print(re.findall("[a-z]","dhghafgzxx"))
print(re.findall("g[a-z]*","dhghafgzxx"))
print(re.findall("g[0-9]*","g8dhghafgzxx"))
#  字符集中的 ^  相当于非
print(re.findall("g[^a-z]","sadffg54172"))

 转义字符

转义字符 意义 ASCII码值(十进制)
\a 响铃(BEL) 007
\b 退格(BS) ,将当前位置移到前一列 008
\f 换页(FF),将当前位置移到下页开头 012
\n 换行(LF) ,将当前位置移到下一行开头 010
\r 回车(CR) ,将当前位置移到本行开头 013
\t 水平制表(HT) (跳到下一个TAB位置) 009
\v 垂直制表(VT) 011
\\ 代表一个反斜线字符”\’ 092
\’ 代表一个单引号(撇号)字符 039
\” 代表一个双引号字符 034
\?
  
代表一个问号
  
063
  
\0 空字符(NULL) 000
\ooo 1到3位八进制数所代表的任意字符 三位八进制
\xhh 1到2位十六进制所代表的任意字符 二位十六进制

re模块下的方法

正则表达式是对字符串的最简约的规则的表述。python也有专门的正则表达式模块re.

正则表达式函数 释义
re.match() 从头开始匹配,匹配失败返回None,匹配成功可通过group(0)返回匹配成功的字符串
re.search() 扫描整个字符串,并返回第一个匹配的字符串
re.sub() 对符合要求的所有子串进行替换
re.findall() 以列表形式返回所有符合条件的子串    
re.split() 以模式作为切分符号切分字符串,并返回列表
re.finditer() 找到 RE 匹配的所有子串,并把它们作为一个迭代器返回
re.compile() 把那些经常使用的正则表达式编译成正则表达式对象
re.group() 返回被 RE 匹配的字符串
re.start() 返回匹配开始的位置
re.end() 返回匹配结束的位置
re.span() 返回一个元组包含匹配 (开始,结束) 的位置

re.fandall

#返回所有满足条件的匹配结果,再放列表里
print(re.findall("[a-z]","dhghafgzxx"))

re.search

# re.search  匹配字符串里面的,只要找到一个就不再往后面找了
# ?P<name>  固定格式 name是分组的名称
# 注意res是一个对象
# 通过调用group方法取出对象中的结果
res = re.search("(?P<name>[a-z]+)(?P<age>\d+)", "szx18alex38")
print(res.group("age"))

 re.match

#从头开始匹配,匹配失败返回None,匹配成功可通过group(0)返回匹配成功的字符串
print(re.match('\d+' ,'1342abcccd' ).group()) #1342

 re.split

#先按"a"分割得到""和"bcd",在对""和"bcd"分别按"b"进行分割
print(re.split('[ab]' ,'abcd' ))  #['', '', 'cd']

 re.sub

#替换 2表示替换几次
print(re.sub('\d','A' ,'1342abcccd',2))

 re.subn

#把结果做成一个元祖,第一个是匹配的内容,第二个是匹配的次数
print(re.subn('\d','A' ,'1342abcccd',2))

 re.compile

#把那些经常使用的正则表达式编译成正则表达式对象
com = re.compile('\d+')
print(com.findall("eubc114"))

 re.finditer

#找到 RE 匹配的所有子串,并把它们作为一个迭代器返回
rec = re.finditer("\d","eubc114")
for i in rec:
    print(i)

 #分组提取() 优先提取分组的值
print(re.findall(“www\.(baidu|163)\.com”,”www.baidu.com”)) #[‘baidu’]
print(re.findall(“www\.(?:baidu|163)\.com”,”www.baidu.com”))#[‘www.baidu.com’]

作者:村里唯一的架构师