re模块

Posted shaozheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了re模块相关的知识,希望对你有一定的参考价值。

正则表达式:

--字符串匹配,进行字符串处理

匹配过程:

依次拿出表达式和文本中的字符比较,如果每一个字符都能匹配,则匹配成功;一旦有匹配不成功的字符则匹配失败

一,

技术图片

贪婪模式及非贪婪模式:

--匹配尽可能多的字符;非贪婪的则相反,总是尝试匹配尽可能少的字符

反斜杠困扰:

需要匹配文本中的字符,那么使用编程语言表示的正则表达式里将需要4个反斜杠\\:前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠

()元字符(分组)

也就是分组匹配,()里面的为一个组也可以理解成一个整体
如果()后面跟的是特殊元字符如(abc)* 那么*控制的前导字符就是()里的整体内容,不再是前导一个字符

|元字符(或)

|或,或就是前后其中一个符合就匹配

re模块中的功能函数:

import re
a = re.findall("匹配规则", "字符串是否有匹配规则的字符")
print(a)
import re
# 将正则表达式编译成Pattern对象
pattern = re.compile(r'hello')

# 使用Pattern匹配文本,获得匹配结果,无法匹配时将返回None
match = pattern.match('hello world!')

if match:
    # 使用Match获得分组信息
    print(match.group())
@在Python的正则表达式中,有一个参数为re.S。它表示 “.” 的作用扩展到整个字符串,包括“
”
----匹配所有字符包括换行符
import re
a = '''asdfhellopass:
    worldaf
    '''
b = re.findall('hello(.*?)world', a)
c = re.findall('hello(.*?)world', a, re.S)
print('b is ', b)
print('c is ', c)
b is  []
c is  ['pass:
    ']

re.l:不区分大小写
res = re.findall(r"A", "abc", re.I)
print(res)
['a']
re.sub-->相当 --replace
re.subn --->replace,后面替代计数
# 要求结果:['12', '23', '34']
l = ['1 2 ', '2   3', '  3 4']
import re
print(eval(re.sub(r's*', '', str(l))))
['12', '23', '34']
re.match(pattern, string[, flags])函数

match(pattern, string, flags=0)

pattern: 正则模型
string : 要匹配的字符串
falgs : 匹配模式

re.match(pattern, string[, flags]):

从头匹配一个符合规则的字符串,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None

注意:match()函数 与 search()函数基本是一样的功能,

不一样的就是match()匹配字符串开始位置的一个符合规则的字符串,search()是在字符串全局匹配第一个合规则的字符串

import re
# 无分组
origin = "hello egon bcd egon lge egon acd 19"
r = re.match("hw+", origin)  # match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None
print(r.group())  # 获取匹配到的所有结果,不管有没有分组将匹配到的全部拿出来
print(r.groups())  # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分的结果
print(r.groupdict())  

re.search(pattern, string[, flags])函数

search,浏览全部字符串,匹配第一符合规则的字符串,浏览整个字符串去匹配第一个,未匹配成功返回None

search(pattern, string, flags=0)

注意:match()函数 与 search()函数基本是一样的功能,不一样的就是match()匹配字符串开始位置的一个符合规则的字符串,search()是在字符串全局匹配第一个合规则的字符串

re.findall(pattern, string[, flags])函数(常用)

浏览全部字符串,匹配所有合规则的字符串,匹配到的字符串放到一个列表中,未匹配成功返回空列表

注意:一旦匹配成,再次匹配,是从前一次匹配成功的,后面一位开始的,也可以理解为匹配成功的字符串,不在参与下次匹配

注意:如果没写匹配规则,也就是空规则,返回的是一个比原始字符串多一位的,空字符串列表

注意:正则匹配到空字符的情况,如果规则里只有一个组,而组后面是就表示组里的内容可以是0个或者多过,

这样组里就有了两个意思,一个意思是匹配组里的内容,二个意思是匹配组里0内容(即是空白)所以尽量避免用否则会有可能匹配出空字符串

注意:正则只拿组里最后一位,如果规则里只有一个组,匹配到的字符串里在拿组内容是,拿的是匹配到的内容最后一位

e.split(pattern, string[, maxsplit])函数

根据正则匹配分割字符串,返回分割后的一个列表

按照一个字符将全部字符串进行分割

将匹配到的字符串作为分割标准进行分割

re.sub(pattern, repl, string[, count])函数

替换匹配成功的指定位置字符串

sub(pattern, repl, string, count=0, flags=0)

  • pattern: 正则模型

  • repl : 要替换的字符串

  • string : 要匹配的字符串

  • count : 指定匹配个数

  • flags : 匹配模式

re.subn(pattern, repl, string,[, count][, flags])函数

替换匹配成功的指定位置字符串,并且返回替换次数,可以用两个变量分别接受

subn(pattern, repl, string, count=0, flags=0)

  • pattern: 正则模型

  • repl : 要替换的字符串

  • string : 要匹配的字符串

  • count : 指定匹配个数

  • flags : 匹配模式

分组函数:

?P<n1> # ?P<>定义组里匹配内容的key(键),<>里面写key名称,值就是匹配到的内容

只对正则函数返回对象的有用

  • group() # 获取匹配到的所有结果,不管有没有分组将匹配到的全部拿出来,有参取匹配到的第几个
  • groups() # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分的结果
  • groupdict() # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分定义了key的组结果

    无分组:匹配所有合规则的字符串,匹配到的字符串放到一个列表中

    有分组:只将匹配到的字符串里,组的部分放到列表里返回,相当于groups()方法

    多个分组:只将匹配到的字符串里,组的部分放到一个元组中,最后将所有元组放到一个列表里返

    相当于在group()结果里再将组的部分,分别,拿出来放入一个元组,最后将所有元组放入一个列表返回

    分组中有分组:只将匹配到的字符串里,组的部分放到一个元组中,先将包含有组的组,看作一个整体也就是一个组,把这个整体组放入一个元组里,然后在把组里的组放入一个元组,最后将所有组放入一个列表返回

  • ?:在有分组的情况下findall()函数,不只拿分组里的字符串,拿所有匹配到的字符串,注意?:只用于不是返回正则对象的函数如findall()

注意事项:

  1. r原生字符:让在python里有特殊意义的字符如,转换成原生字符(就是去除它在python的特殊意义),不然会给正则表达式有冲突,为了避免这种冲突可以在规则前加原始字符r

  2. 正则表达式,返回类型为表达式对象的,如:<_sre.SRE_Match object; span=(6, 7), match=‘a‘>,返回对象时,需要用正则方法取字符串,方法有:

    1. group() # 获取匹配到的所有结果,不管有没有分组将匹配到的全部拿出来,有参取匹配到的第几个如2

    2. groups() # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分的结果

    3. groupdict() # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分定义了key的组结果

  3. 匹配到的字符串里出现空字符:注意:正则匹配到空字符的情况,如果规则里只有一个组,而组后面是就表示组里的内容可以是0个或者多过,这样组里就有了两个意思,一个意思是匹配组里的内容,二个意思是匹配组里0内容(即是空白)所以尽量避免用否则会有可能匹配出空字符串

  4. ()分组:注意:分组的意义,就是在匹配成功的字符串中,再提取()里的内容,也就是组里面的字符串

  5. ?:在有分组的情况下findall()函数,不只拿分组里的字符串,拿所有匹配到的字符串,注意?:只用于不是返回正则对象的函数如findall()

元字符:
 ^  以什么 开头
 $   以什么 结尾
 .  任意字符(一个)
 d  数字(所有)
 w 非空(所有)
 s 空  空格 (
 	)
 D 非数字
 W 空
 S 非空

+ 前面的字符至少一个
? 前面的字符 0--1个
* 前面的字符至少零个
[] 中扩号内的都可以
[^] 中扩号内的都不可以
| 或
{n} 前面的字符n个
贪婪模式(.*), 非贪婪模式【.*?】

a(?=d) a后面+ 数字 但不要数字 ---》a. ,不消耗字符串的内容
^w+@w+.com


功能函数:
re.findall()
re.compile() -编译

res = re.match() ----->从头开始,拿到一个返回值,就不找了.找不到就报错
--》res.group() -->接收,打印

res = re.search()  --从字符串找拿到一个返回值,就不找了
--》res.group() -->接收,打印

re.split() ---区分

re.sub() -->replace

re.subn() --->replace -->计算替换的次数
补充:
re.S --->修饰符(匹配所有字符)
会让 `.`匹配换行


分组: ---只要括号里的(元组)
有名分组:
---》print(re.search('a(?P<name>.)c(?P<name2>d)',s).groupdict()) --->字典取出
正则运用:
import re

expression = '-1-2*((60+2*(-3-40.0+42425/5)*(9-2*5/3+357/553/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))+56+(56-45)'
question = eval(expression)
print(question)


def arithmetic(expression='1+1'):
    #     content = re.search('(([-+*/]*d+.?d*)+)', expression)  # (-3-40.0/5)
    content = re.search('(([-+*/]*d+.?d*)+)', expression)  # (-3-40.0/5)
    if content:
        content = content.group()
        content = content[1:-1]
        print('content:', content)
        replace_content = next_arithmetic(content)
        expression = re.sub('(([-+*/]*d+.?d*)+)',
                            replace_content,
                            expression,
                            count=1)
        print('next_expression:', expression)
    else:
        answer = next_arithmetic(expression)
        return answer
    return arithmetic(expression)


def next_arithmetic(content):
    while True:
        next_content_mul_div = re.search('d+.?d*[*/][-+]?d+.?d*',
                                         content)  # 找出带有*/的式子
        if next_content_mul_div:  # 如果content含有带有*/的式子
            next_content_mul_div = next_content_mul_div.group()
            print('next_content_mul_div:', next_content_mul_div)
            mul_div_content = mul_div(next_content_mul_div)  # 计算出带有*/的式子
            print('mul_div_content:', mul_div_content)
            content = re.sub('d+.?d*[*/][-+]?d+.?d*',
                             str(mul_div_content),
                             content,
                             count=1)  # 把带有*/的式子计算出来后替换掉
            print('content:', content)
            continue
        next_content_add_sub = re.search('-?d+.?d*[-+][-+]?d+.?d*',
                                         content)  # 找出带有-+的式子
        if next_content_add_sub:  # 如果content含有带有+-的式子
            next_content_add_sub = next_content_add_sub.group()
            print('next_content_add_sub:', next_content_add_sub)
            add_sub_content = add_sub(next_content_add_sub)  # 计算出带有-+的式子
            print('add_sub_content:', add_sub_content)
            add_sub_content = str(add_sub_content)
            content = re.sub('-?d+.?d*[-+]-?d+.?d*',
                             str(add_sub_content),
                             content,
                             count=1)  # 把带有-+的式子计算出来后替换掉
            print('content:', content)
            continue
        else:
            break
    return content


def add_sub(content):
    if '+' in content:
        content = content.split('+')
        print(content)
        content = float(content[0]) + float(content[1])
        return content
    elif '-' in content:
        content = content.split('-')
        # 减法情况有多种
        if content[0] == '-' and content[2] == '-':
            # content = content.split('-')
            print(content)
            content = -float(content[1]) - float(content[-1])
            return content
        if content[0] == '-':
            # content = content.split('-')
            print(content)
            content = -float(content[1]) - float(content[-1])
            return content
        if content[1] == '-' and content[2] == '-':
            # content = content.split('-')
            print(content)
            content = -float(content[0]) + float(content[-1])
            return content
        if content[1] == '':
            # content = content.split('-')
            print(content)
            content = float(content[0]) - float(content[2])
            return content
        if content[0] == '' and content[2] != '':
            print(content)
            content = -float(content[1]) - float(content[2])
            return content
        if content[0] == '' and content[2] == '':
            print(content)
            content = -float(content[1]) + float(content[3])
            return content
        else:
            # content = content.split('-')
            print(content)
            content = float(content[0]) - float(content[1])
            return content


def mul_div(content):
    if '*' in content:
        content = content.split('*')
        print(content)
        content = float(content[0]) * float(content[1])
        return content
    elif '/' in content:
        content = content.split('/')
        print(content)
        content = float(content[0]) / float(content[1])
        return content


# expression = '1-2*((60+2*(-3-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'
expression = '-1-2*((60+2*(-3-40.0+42425/5)*(9-2*5/3+357/553/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))+56+(56-45)'
answer = arithmetic(expression)
print(answer)
-553071849.7670887
content: -3-40.0+42425/5
next_content_mul_div: 42425/5
['42425', '5']
mul_div_content: 8485.0
content: -3-40.0+8485.0
next_content_add_sub: -3-40.0
['', '3', '40.0']
add_sub_content: -43.0
content: -43.0+8485.0
next_content_add_sub: -43.0+8485.0
['-43.0', '8485.0']
add_sub_content: 8442.0
content: 8442.0
next_expression: -1-2*((60+2*8442.0*(9-2*5/3+357/553/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))+56+(56-45)
content: 9-2*5/3+357/553/3*99/4*2998+10*568/14
next_content_mul_div: 2*5
['2', '5']
mul_div_content: 10.0
content: 9-10.0/3+357/553/3*99/4*2998+10*568/14
next_content_mul_div: 10.0/3
['10.0', '3']
mul_div_content: 3.3333333333333335
content: 9-3.3333333333333335+357/553/3*99/4*2998+10*568/14
next_content_mul_div: 357/553
['357', '553']
mul_div_content: 0.6455696202531646
content: 9-3.3333333333333335+0.6455696202531646/3*99/4*2998+10*568/14
next_content_mul_div: 0.6455696202531646/3
['0.6455696202531646', '3']
mul_div_content: 0.21518987341772153
content: 9-3.3333333333333335+0.21518987341772153*99/4*2998+10*568/14
next_content_mul_div: 0.21518987341772153*99
['0.21518987341772153', '99']
mul_div_content: 21.303797468354432
content: 9-3.3333333333333335+21.303797468354432/4*2998+10*568/14
next_content_mul_div: 21.303797468354432/4
['21.303797468354432', '4']
mul_div_content: 5.325949367088608
content: 9-3.3333333333333335+5.325949367088608*2998+10*568/14
next_content_mul_div: 5.325949367088608*2998
['5.325949367088608', '2998']
mul_div_content: 15967.196202531646
content: 9-3.3333333333333335+15967.196202531646+10*568/14
next_content_mul_div: 10*568
['10', '568']
mul_div_content: 5680.0
content: 9-3.3333333333333335+15967.196202531646+5680.0/14
next_content_mul_div: 5680.0/14
['5680.0', '14']
mul_div_content: 405.7142857142857
content: 9-3.3333333333333335+15967.196202531646+405.7142857142857
next_content_add_sub: 9-3.3333333333333335
['9', '3.3333333333333335']
add_sub_content: 5.666666666666666
content: 5.666666666666666+15967.196202531646+405.7142857142857
next_content_add_sub: 5.666666666666666+15967.196202531646
['5.666666666666666', '15967.196202531646']
add_sub_content: 15972.862869198312
content: 15972.862869198312+405.7142857142857
next_content_add_sub: 15972.862869198312+405.7142857142857
['15972.862869198312', '405.7142857142857']
add_sub_content: 16378.577154912598
content: 16378.577154912598
next_expression: -1-2*((60+2*8442.0*16378.577154912598)-(-4*3)/(16-3*2))+56+(56-45)
content: 60+2*8442.0*16378.577154912598
next_content_mul_div: 2*8442.0
['2', '8442.0']
mul_div_content: 16884.0
content: 60+16884.0*16378.577154912598
next_content_mul_div: 16884.0*16378.577154912598
['16884.0', '16378.577154912598']
mul_div_content: 276535896.68354434
content: 60+276535896.68354434
next_content_add_sub: 60+276535896.68354434
['60', '276535896.68354434']
add_sub_content: 276535956.68354434
content: 276535956.68354434
next_expression: -1-2*(276535956.68354434-(-4*3)/(16-3*2))+56+(56-45)
content: -4*3
next_content_mul_div: 4*3
['4', '3']
mul_div_content: 12.0
content: -12.0
next_expression: -1-2*(276535956.68354434--12.0/(16-3*2))+56+(56-45)
content: 16-3*2
next_content_mul_div: 3*2
['3', '2']
mul_div_content: 6.0
content: 16-6.0
next_content_add_sub: 16-6.0
['16', '6.0']
add_sub_content: 10.0
content: 10.0
next_expression: -1-2*(276535956.68354434--12.0/10.0)+56+(56-45)
content: 276535956.68354434--12.0/10.0
next_content_mul_div: 12.0/10.0
['12.0', '10.0']
mul_div_content: 1.2
content: 276535956.68354434--1.2
next_content_add_sub: 276535956.68354434--1.2
['276535956.68354434', '', '1.2']
add_sub_content: 276535955.48354435
content: 276535955.48354435
next_expression: -1-2*276535955.48354435+56+(56-45)
content: 56-45
next_content_add_sub: 56-45
['56', '45']
add_sub_content: 11.0
content: 11.0
next_expression: -1-2*276535955.48354435+56+11.0
next_content_mul_div: 2*276535955.48354435
['2', '276535955.48354435']
mul_div_content: 553071910.9670887
content: -1-553071910.9670887+56+11.0
next_content_add_sub: -1-553071910.9670887
['', '1', '553071910.9670887']
add_sub_content: -553071911.9670887
content: -553071911.9670887+56+11.0
next_content_add_sub: -553071911.9670887+56
['-553071911.9670887', '56']
add_sub_content: -553071855.9670887
content: -553071855.9670887+11.0
next_content_add_sub: -553071855.9670887+11.0
['-553071855.9670887', '11.0']
add_sub_content: -553071844.9670887
content: -553071844.9670887
-553071844.9670887

以上是关于re模块的主要内容,如果未能解决你的问题,请参考以下文章

python 正则表达式 re模块基础

如何使用模块化代码片段中的LeakCanary检测内存泄漏?

Python基础之re模块

如何有条件地将 C 代码片段编译到我的 Perl 模块?

python re模块findall()详解

Node.js JavaScript 片段中的跳过代码