python正则表达式2

python正则表达式

 一、正则修饰符

修饰符
描述
re.I
使匹配对大小写不敏感
re.M
多行匹配,影响^和$
re.S
使.匹配包括换行在内的所有字符
 
#.表示除了换行以外的任意字符
import re
m=re.search(r'm.*a','adfamo\nejoald')
print(m)    #None
m1=re.search(r'm.*a','adfamo\nejoald',re.S)   
print(m1)       #<re.Match object; span=(4, 11), match='mo\nejoa'>

m1=re.search(r'b','aBc')
print(m1)    #None
m2=re.search(r'b','aBc',rs.I)
print(m2)    #<re.Match object; span=(1, 2), match='B'>

#\w:表示的是字母数字和_   +:出现一次以上    $:以指定的内容结尾
m3=re.findall(r'\w+$','i am boy\n you are girl\n he is man')
print(m3)   #['man']
m4=re.findall(r'\w+$','i am boy\n you are girl\n he is man',re.M)
print(m4)   #['boy', 'girl', 'man']

  

二、正则表达式模式

       模式字符串使用特殊的语法来表示一个正则表达式。

       1、字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。

ret=re.search(r'H','Hello')   #H表示字母H本身

  2、多数字母和数字前加一个反斜杠时会拥有不同的含义。

ret=re.search(r'\d','ab34d2')   #这里的\d表示匹配的是数字

  3、标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。

ret=re.search(r'.','hello')   #这里的.表示匹配任意一个字符
ret=re.search(r'\.','hel.o')  #这里的.进行了转义,表示标点符号自身

  反斜杠本身需要使用反斜杠转义。由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如 r'\t',等价于 \\t )匹配相应的特殊字符。

 

       下表列出了正则表达式模式语法中的特殊元素。如果你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。

  • 非打印字符

       非打印字符也可以是正则表达式的组成部分。下表列出了表示非打印字符的转义序列:

字 符
描 述
\cx
匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。
\f
匹配一个换页符。等价于 \x0c 和 \cL。
\n
匹配一个换行符。等价于 \x0a 和 \cJ。
\r
匹配一个回车符。等价于 \x0d 和 \cM。
\s
匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。
\S
匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\t
匹配一个制表符。等价于 \x09 和 \cI。
\v
匹配一个垂直制表符。等价于 \x0b 和 \cK。
 
 

import re

# \s  表示任意的空白字符(空格、换行、制表符)
print(re.search(r'\s', 'hello world'))  # 空格
# <re.Match object; span=(5, 6), match=' '>

print(re.search(r'\n', 'hello\nworld'))  # 换行
# <re.Match object; span=(5, 6), match='\n'>

print(re.search(r'\t', 'hello world'))  # 制表符
# None

# \S  表示非空白字符
print(re.search(r'\S', '\t\n  x'))
# <re.Match object; span=(4, 5), match='x'>
  • 特殊字符
       所谓特殊字符,就是一些有特殊含义的字符。若要匹配这些特殊字符,必须首先使字符"转义",即,将反斜杠字符\ 放在它们前面。下表列出了正则表达式中的特殊字符:
特殊字符
                                                   描    述
$
匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身,请使用 \$。
( )
标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。
*
匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。
+
匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。
.
匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \. 。
[
标记一个中括号表达式的开始。要匹配 [,请使用 \[。
?
匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。
\
将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\",而 '\(' 则匹配 "("。
^
匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 \^。
{
标记限定符表达式的开始。要匹配 {,请使用 \{。
|
指明两项之间的一个选择。要匹配 |,请使用 \|。
\d
匹配一个数字字符。等价于[0-9]。
[0-9]
匹配任何数字。等价于\d
\D
匹配一个非数字字符。等价于[^0-9]。
[a-z]
匹配任何小写字母
[A-Z]
匹配任何大写字母
[a-zA-Z0-9]
匹配任何字母及数字。
\w
匹配包括下划线的任何任何数字字母。等价于[a-zA-Z0-9_]。
\W
匹配任何非下划线数字字母。等价于[^a-zA-Z0-9_]。
[\u4e00-\u9fa5]
匹配纯中文。

  •  定位符
       定位符能够将正则表达式固定到行首或行尾。它们还能够创建这样的正则表达式,这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。

       定位符用来描述字符串或单词的边界,^ 和 $ 分别指字符串的开始与结束,\b 描述单词的前或后边界,\B 表示非单词边界。

 
       正则表达式的定位符有:
字符
                                           描    述
^
匹配输入字符串的开始位置,例如:^h匹配以h开头;除非在方括号表达式中使用,此时它表示不接受该字符集合,例如[^0-9]匹配除了数字以外的数据。要匹配 ^ 字符本身,请使用 \^。
$
匹配输入字符串结尾的位置。如果设置了 Multiline 属性,$ 还会与 \n 或 \r 之前的位置匹配。要匹配 $ 字符本身,请使用 \$。
\b
匹配一个单词边界,即单词与空格间的位置。
\B
非单词边界匹配。

  •  限定字符
       限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有****或+或?或{n}或{n,}或{n,m}共6种。

       正则表达式的限定符有:

字符
描述
*
匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。
+
匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
?
匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 、 "does" 中的 "does" 、 "doxy" 中的 "do" 。? 等价于 {0,1}。
{n}
n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。
{n,}
n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。
{n,m}
m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。

 示例:

import re

#():用来表示一个分组
m=re.search(r'h(\d+)x','sh283xkfa')
print(m.group(),m.group(0),m.group(1))   #h283x h283x 283
m1=re.search(r'\(.*\)','(1+1)*3+5')
print(m1.group())        # (1+1)

# . :用来匹配除了换行以外的任意字符。如果要匹配 .  需要使用 \.

# [ ] :表示可选项范围  #[x,y] 从x到y区间,包括x和y
m2=re.search(r'f[a-d]m','pdsfcmsb')
print(m2)   #<re.Match object; span=(3, 6), match='fcm'>

# | :用来表示或者
m3=re.search(r'f(x|pro|t)m','adfpromw4')
print(m3)   #<re.Match object; span=(2, 7), match='fprom'>

# {}:用来限定前面元素出现的次数
#{n}:表示前面的元素出现n次
#{n,}:表示前面的元素出现n次以上
#{,n}:表示前面的元素出现n次以下
#{n,m}:表示前面的元素出现m次到n次
print(re.search(r'go{2}','good').group())    #goo
print(re.search(r'go{2,}','gooooood').group())   #goooooo

# *:表示前面的元素出现任意次数,等价于{0,}
print(re.search(r'go*', 'gooooooood').group())   #goooooooo

# +:表示前面的元素至少出现一次,等价于{1,}
#print(re.search(r'go+', 'gd').group())   #出错

#?:两种用法:
#1.规定前面的元素最多出现一次,等价于{,1}
#2.将贪婪模式转换成非贪婪模式
print(re.search(r'go?d', 'gd').group())   #  gd

# ^:字符串以指定的内容开头    $:指定内容结束
print(re.search(r'^a.*x$', 'abcx'))   # abcx
#^:在[]里还可以表示取反
print(re.search(r'a[^0-9]+x','faypxm5d'))   #aypx

  

 三、正则表达式练习

        判断用户输入内容是否是数字,如果是数字转换为数字类型:

import re
num=input('请输入一段数字')
if re.fullmatch(r'\d+\.?\d*',num):
    print('是个数字')
    print(float(num))
else:
    print('不是一个数字')

  邮箱论证:

^([A-Za-z0-9_\-\.])+@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$

  身份证论证:

^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$

  

 四、正则替换

       正则表达式作用是用来对字符串进行检索和替换

       检索:match  search  fullmatch  finditer  findall

       替换:sub

       python中的re模块提供了re.sub用来替换字符串中的匹配项

       语法:

re.sub(pattern,repl,string,count=0)

  由于字符串是不可变数据类型,因此用re.sub替换后生成新的字符串。

       参数:

              pattern:正则中的模式字符串
              repl:替换的字符串,也可为一个函数
              string:要被查找替换的原始字符串
              count:模式匹配后替换的最大次数,默认0表示替换所有的匹配

       

import re

phone = '138-0021-4576  #这是一个电话号码'
# 删除注释
num = re.sub(r'#.*$', '', phone)
print(num)
# 138-0021-4576
# 移除非数字
num1 = re.sub(r'\D', '', phone)
print(num1)
# 13800214576

  

       repl可以使用一个字符串来表示替换后的结果以外,还可以传入一个函数。
def double(matched):
    test = int(matched.group('test'))
    return str(test * 2)


print(re.sub(r'(?P<test>\d+)', double, 'hello23hi34'))

  

五、贪婪与非贪婪

       python里数量词默认是贪婪的(在少数语言里也可能默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪则相反,总是尝试匹配尽可能少的字符。
 
       在 *、?、+、{m,n}后面加上?,使贪婪变成非贪婪。

 

import re
m=re.search(r'm.*a','e3fms6ajxxa9g')
print(m.group())   #ms6ajxxa      贪婪模式
n=re.search(r'm.*?a','e3fms6ajxxa9g')
print(n.group())   #ms6a         非贪婪模式

  正则表达式模式中使用到通配符,那它从左向右的顺序求值时,会尽量“抓取”满足匹配最长字符串,在我们上边的例子中,“.*”会从字符串的开始处抓取满足模式的最字符串,在字符串中抓取到后一个“a”之前的所有字符,即“ms6ajxxa”。而“.*?”会从开始处抓取满足模式的最字符串,在字符串中抓取到第一个“a”后,结束匹配,即“ms6a ”。

import re
m1=re.match(r'aa(\d+)','aa3345bbb')
print(m1.group(0),m1.group(1))    #aa3345    3345

m2=re.match(r'aa(\d+?)','aa3345bbb')
print(m2.group(0),m2.group(1))    #aa3     3

m3=re.match(r'aa(\d+)bbb','aa3345bbb')
print(m3.group(0),m3.group(1))     #aa3345bbb    3345

m4=re.match(r'aa(\d+?)bbb','aa3345bbb')
print(m4.group(0),m4.group(1))     #aa3345bbb    3345

m5=re.match(r'aa(\d+?).*','aa3345bbb')
print(m5.group(0),m5.group(1))     #aa3345bbb    3

m6=re.match(r'aa(\d??)(.*)','aa3345bbb')
print(m6.group(0),m6.group(1),m6.group(2))     #aa3345bbb  空  3345bbb

  示例:

字符串为:

<imag data-original='https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg' src='https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg' style='display:inline;'>

提取url地址:

re.search(r'https://.*?\.jpg',test)

   

 

posted @ 2021-03-16 15:42  wangshanglinju  阅读(121)  评论(0编辑  收藏  举报