Python基础14 模块(3)常用标准库模块 re 正则表达式

本文详细介绍了Python中的re正则表达式,包括其定义、作用以及re模块中的常用方法如findall、search、match、split、sub、subn、compile和finditer。还涵盖了元字符、普通字符、字符集、边界匹配和分组的使用示例。
摘要由CSDN通过智能技术生成

一、re 正则表达式的定义和作用

正则表达式是一种小型、高度专业化的编程语言。
作用:进行字符串模糊匹配

二、普通字符

绝大部分的字符都是普通字符,比如数字和字母。
普通字符是进行完全匹配。

三、元字符

. 通配符(除了 \n不能匹配,可以匹配其他任意一个字符)
^ 以该字符串开头
$ 以该字符串结尾
* 重复前一个字符,0~无穷次
+ 重复前一个字符,1~无穷次
? 匹配前一个字符,0~1个
{ } 自定义重复范围,例:
{0,} 重复0~无穷次
{1,2} 重复1~2次
{6} 重复6次
注:默认上述元字符均为贪婪匹配,后面加 ,变为惰性匹配

import re

v1 = re.findall("a..b", "baasbartb")
print(v1)  # ['aasb', 'artb']
v2 = re.findall("^ba", "baasbartb")
print(v2)  # ['ba']
v3 = re.findall("tb$", "baasbartb")
print(v3)  # ['tb']
v4 = re.findall("a*", "baasbartb")
print(v4)  # ['', 'aa', '', '', 'a', '', '', '', '']
v5 = re.findall("a+", "baasbartb")
print(v5)  # ['aa', 'a']
v6 = re.findall("a?", "baasbartb")
print(v6)  # ['', 'a', 'a', '', '', 'a', '', '', '', '']
v7 = re.findall("a{1,2}", "baasbartaaab")
print(v7)  # ['aa', 'a', 'aa', 'a']
v8 = re.findall("a{1,2}?", "baasbartaaab")
print(v8)  # ['a', 'a', 'a', 'a', 'a', 'a']

[ ] 字符集,选其中一个元素。字符集内部,除了 \ - ^ ,均为普通字符。其中 - 表示范围,^ 表示非,\ 表示转义字符
\ 转义字符,作用:
(1)将有意义的元字符变成普通字符
(2)将无意义的普通字符变为有意义的特殊字符
\d 匹配任何十进制数
\D 匹配任何非数字字符
\s 匹配任何空白字符
\S 匹配任何非空白字符
\w 匹配任何字母数字字符和_
\W 匹配任何非字母数字字符和_

import re

v1 = re.findall("[1-9]+", "baas1ba125rtb")
print(v1)  # ['1', '125']
v2 = re.findall("[^1-9]+", "baas1ba125rtb")
print(v2)  # ['baas', 'ba', 'rtb']
v3 = re.findall("[\d]+", "baas1ba125rtb")
print(v3)  # ['1', '125']
v4 = re.findall("[\D]+", "baas1ba125rtb")
print(v4)  # ['baas', 'ba', 'rtb']
v5 = re.findall("[\s]+", "baas1b    a125rtb")
print(v5)  # ['    ']
v6 = re.findall("[\S]+", "baas1b    a125rtb")
print(v6)  # ['baas1b', 'a125rtb']
v7 = re.findall("[\w]+", "baas1b    a1_2*5rtb")
print(v7)  # ['baas1b', 'a1_2', '5rtb']
v8 = re.findall("[\W]+", "baas1b    a1_2*5rtb")
print(v8)  # ['    ', '*']

\b 匹配以一个特殊字符作为边界,比如空格,&,#等。

import re

#以I开始
v1 = re.findall("\\bI", "Ia am I LoIo")
print(v1)  # ['I', 'I']

#以I结束
v2 = re.findall("I\\b", "Ia am I LoIo")
print(v2)  # ['I']

注:代码先传给Python解释器进行解释,再传给被调用的re模块。由于\b为Python内置的字符,需要写\\b,或者写r"\b",才能保证传给re模块的代码为\b。 类似的,如下:

import re

v1 = re.findall("\\\\l", "wwf\lgxa")
print(v1)  # ['\\l']
v2 = re.findall(r"\\l", "wwf\lgxa")  # 传递原生字符串
print(v2)  # ['\\l']

| 或者

import re

v1 = re.search("a(b|c)d", "abdc").group()
print(v1)  # abd

() 分组,内部看成一个整体
注:在findall方法中,会优先匹配分组的字符串,忽略其他部分。

import re

v1 = re.findall("www(baidu)com", "qewwwbaiducomzff")
print(v1)  # ['baidu']
v2 = re.search("www(baidu)com", "qewwwbaiducomzff").group()
print(v2)  # wwwbaiducom
# 加 ?: 可以取消分组优先
v3 = re.findall("www(?:baidu)com", "qewwwbaiducomzff")
print(v3)  # ['wwwbaiducom']

四、re模块常用方法

1、findall

返回所有满足匹配条件的结果,放在列表里。

import re

v1 = re.findall("\d+", "wded123fw54")
print(v1)  # ['123', '54']

2、search

只返回第一个查到结果,构成的对象。可通过group方法得到匹配的字符串。没查到结果,返回None

v2 = re.search("\d+", "wded123fw54").group()
print(v2)  # 123

v3 = re.search("\d{5}}", "wded123fw54")
print(v3)   # None

3、match

类似search,但只从字符串开头匹配。

v = re.match("\d+", "wded123fw54")
print(v)  # None

4、split

分割

v1 = re.split('\d+',"wded123fw54")
print(v1)  # ['wded', 'fw', '']

v2 = re.split('\d+',"wded123fw54a",1)
print(v2)  # ['wded', 'fw54a']

5、sub

替换

v1 = re.sub('\d+',"A","wded123fw54")
print(v1)  # wdedAfwA

v2 = re.sub('\d+',"A","wded123fw54",1)
print(v2)  # wdedAfw54

6、subn

返回一个元组,(匹配结果,匹配个数)

v1 = re.subn('\d+',"A","wded123fw54")
print(v1)  # ('wdedAfwA', 2)

7、compile

编译

co = re.compile("\d+")
v = co.findall("wded123fw54")
print(v)    # ['123', '54']

8、finditer

类似findall方法,但是返回的是一个迭代器

v1 = re.finditer("\d+", "wded123fw54")
print(v1)  # <callable_iterator object at 0x000002676E7004C0>
print(v1.__next__().group())    # 123
print(v1.__next__().group())    # 54

五、字符串匹配的其他用法

v4 = re.search("(?P<name>[a-z]+)(?P<age>\d+)", "wded123fw54").group("name")
print(v4)   # wded
v5 = re.search("(?P<name>[a-z]+)(?P<age>\d+)", "wded123fw54").group("age")
print(v5)   # 123

六、小练习:计算器

用户输入一个类似这样 3*( 4+ 50 )-(( 100 + 40 )5/2- 32* 2/4+9)*((( 3 + 4)-4)-4) 这样的表达式,然后自己动手写代码解析其中的表达式,实现加减乘除。

import re


def multiply_divide(s): # 最小乘除法计算单元
    ret = float(s.split('*')[0]) * float(s.split('*')[1]) if '*' in s else float(s.split('/')[0]) / float(s.split('/')[1])
    return ret


def remove_md(s):   # 消除s中所有的乘除法
    if '*' not in s and '/' not in s:   # s中没有乘除法,直接返回
        return s
    else:   # s中有乘除法,消除左边第一个乘除法算式
        k = re.search(r'-?[\d.]+[*/]-?[\d.]+', s).group()
        s = s.replace(k, '+' + str(multiply_divide(k))) if len(re.findall(r'-', k))%2 == 0 else s.replace(k, str(multiply_divide(k)))
        # 遇到例如 1+2*3 的情况,2*3的计算结果前面需要加“+”,即'+' + str(multiply_divide(k)),不然输出为16
        return remove_md(s)


def add_sub(s): # 从左到右计算加减法
    while re.findall("[+-]{2}", s):
        s = s.replace("++", "+")
        s = s.replace("--", "+")
        s = s.replace("+-", "-")
        s = s.replace("-+", "-")

    l = re.findall('[\d.]+|-|\+', s)
    if l[0] == '-': # 首元为负号,则合并第一二个元素为一个负数
        l[0] = l[0] + l[1]
        del l[1]
    sum = float(l[0])

    for i in range(1, len(l), 2):
        if l[i] == '+':
            sum += float(l[i + 1])
        else:
            sum -= float(l[i + 1])
    return sum


def basic_operation(s):
    s = s.replace(' ', '')
    return add_sub(remove_md(s))

def calculate(expression):  # 处理含有小括号的算式
    if not re.search(r'\([^()]+\)', expression):  # 匹配最里面的括号,如果没有的话,直接进行运算,得出结果
        return basic_operation(expression)

    k = re.search(r'\([^()]+\)', expression).group()  # 将匹配到的括号里面的表达式交给basic_operation处理后重新拼接成字符串递归处理
    expression = expression.replace(k, str(basic_operation(k[1:len(k) - 1])))
    return calculate(expression)

s = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
print('用eval计算出来的值为:{}\n计算器计算出来的值为:{}'.format(eval(s), calculate(s)))
# >>> 用eval计算出来的值为:2776672.6952380957
# >>> 计算器计算出来的值为:2776672.6952380957 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值