Py西游攻关之正则表达式

一简介

      就其本质而言,正则表达式(或 RE)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

 

二 元字符

    字符匹配(普通字符,元字符):    

1   普通字符:大多数字符和字母都会和自身匹配

>>> re.findall('alex','yuanaleSxalexwupeiqi')
['alex']

2    元字符:    .  ^  $    *    +    ?  { }    [ ]  |  ( )  \

没有元字符,正则表达式什么都不是!那接下来咱们就研究下元字符。

2.1  (贪婪匹配)   

      从前面的描述可以看到'*','+'和'?'都是贪婪的,但这也许并不是我们说要的,所以,可以在后面加个问号,将策略改为非贪婪,只匹配尽量少的RE。示例,体会两者的区别: 

>>> re.findall(r"a(\d+?)","a23b") # 非贪婪模式
['2']
>>> re.findall(r"a(\d+)","a23b")
['23']

>>> re.search('<(.*)>', '<H1>title</H1>').group()
'<H1>title</H1>'
re.search('<(.*?)>', '<H1>title</H1>').group()
'<H1>'

     

注意比较这种情况:
>>> re.findall(r"a(\d+)b","a23b")
['23']
>>> re.findall(r"a(\d+?)b","a23b") #如果前后均有限定条件,则非匹配模式失效
['23']

 

2.2 (元字符[])

    []:它们常用来指定一个字符类别,所谓字符类就是你想匹配的一个字符集。字符可以单个列出,也可以用“-”号分隔的两个给定字符来表示一个字符区间。例如,[abc] 将匹配"a", "b", 或 "c"中的任意一个字符;也可以用区间[a-c]来表示同一字符集,和前者效果一致。如果你只想匹配小写字母,那么 RE 应写成 [a-z].元字符在类别里并不起作用。例如,[akm$]将匹配字符"a", "k", "m", 或 "$" 中的任意一个;"$"通常用作元字符,但在字符类别里,其特性被除去,恢复成普通字符。

     例: re.search("[\d]","abc3").group()

 

2.3 (元字符 \ )

    反斜杠后边跟元字符去除特殊功能,反斜杠后边跟普通字符实现特殊功能。

   

 

 

 

 

 

 

 

 

 

 

 

 

计算器:

        

import re



def add_op(arg):  # 定义加法函数
    arg = arg.replace("++", "+").replace("--", "+").replace("+-", "-").replace("-+", "-")  

# 替换符号
    num = re.findall("([+\-]?\d+\.?\d*)", arg)  #匹配所有数字
    result = 0
    for i in num:   #循环数字列表进行累加
        result = result + float(i)
    return result

def mul(arg):   #定义乘除函数
    while True:
        result = re.split("(\d+\.?\d*[\*/][\+-]?\d+\.?\d*)",arg,1) #匹配乘法或除法
        if len(result) == 3:
            bef,cen,aft = result
            if "*" in cen:  #判断乘号是否在cen里面
                num1,num2 = cen.split("*")  #将乘号进行分割得到乘数
                new_cen = float(num1) * float(num2)     #将乘数相乘得到乘积
                arg = bef +str(new_cen) + aft   #将乘积放入新的字符串表达式
            elif "/" in cen:    #判断除号是否在cen里面
                num1,num2 = cen.split("/")  #分割除号得到除数和被除数
                new_cen = float(num1) / float(num2)     #进行除法运算
                arg = bef + str(new_cen) + aft      #将商放入新的字符串表达式
        else:
            return add_op(arg)

def calc(arg):
    while True:
        arg = arg.replace(" ","")
        result = re.split("\(([^()]+)\)",arg,1)     #匹配最里面的括号并且只取括号中的内容
        if len(result) == 3:
            bef,cen,aft = result
            # 计算括号中的表达式,先乘除后加减,得到计算结果
            r = mul(cen)
            #使用计算结果组成新的字符串表达式
            arg = bef + str(r) + aft
        else:   #计算完括号后开始按照先乘除再加减的运算
            return mul(arg)

origin = "1 - 2 * ( (60 - 30 + (-40.0/5) * 3))"
r = calc(origin)
print(r)
print(eval(origin))

 

posted @ 2016-07-26 16:23  Yuan先生  阅读(1248)  评论(0编辑  收藏  举报