正则表达式与re模块

正则表达式

正则表达式是对字符串操作的一种逻辑公式.我们一般使用正则表达式对字符串进行匹配和过滤.
使用正则的优缺点:
优点: 灵活, 功能性强, 逻辑性强.
缺点: 上手难. 一旦上手, 会爱上这个东西
元字符
'.' 默认匹配除\n之外的任意一个字符,若指定flag DOTALL, 则匹配任意字符,包括换行
'^' 匹配字符开头,若指定flags MULTILINE, 这种也可以匹配上(r"^a", "\nabc\neee", flags=re.MULTILINE)
'$' 匹配字符结尾,或e.search("foo$", "bfoo\nsdfsf", flags=re.MULTILINE).group()也可以
'|' 匹配 | 左或 | 右的字符,re.search("abc|ABC", "ABCBabcCD").group()结果 'ABC'
'(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group()结果abcabca456c
'\A' 只从字符开头匹配,re.search("\Aabc", "alexabc")是匹配不到的
'\Z' 匹配字符结尾,同$
'\d' 匹配数字0 - 9
'\D' 匹配非数字
'\w' 匹配[A - Za - z0 - 9]
'\W' 匹配非[A - Za - z0 - 9]
's' 匹配空白字符、\t、\n、\r, re.search("\s+", "ab\tc1\n3").group()结果'\t'' \

量词
'*' 匹配 * 号前的字符0次或多次,
'+' 匹配前一个字符1次或多次,
'?' 匹配前一个字符1次或0次,尽可能的少
'{m}' 匹配前一个字符m次
'{n,m}' 匹配前一个字符n到m次,
转义
在正则:
\.
\元字符
python
"\\."
r"\."
惰性匹配
* + {} 都是贪婪匹配,尽可能多的匹配到结果
.? +? {}? ,惰性匹配,尽可能少的匹配
量词后面加问号
.*?abc 一直取遇到abc就停
分组
() 优先级最高
/1 再次匹配第一个分组

  1 import re
  2 
  3 # 常用语法:
  4 # re.findall 把所有匹配到的字符放到以列表中的元素返回
  5 # re.finditer()   # 与findall相同,返回的是迭代器
  6 # re.search 会进行匹配. 但是如果匹配到了第一个结果. 就会返回这个结果. 如果匹配不上search返回的则是None
  7 # re.match 从头开始匹配
  8 # re.splitall 以匹配到的字符当做列表分隔符
  9 # re.sub      匹配字符并替换
 10 # compile 编译 :正则表达式很长且要多次使用
 11 
 12 
 13 # ret = re.findall('[a-z]+', 'eva egon yuan')
 14 # 返回所有满足匹配条件的结果,放在列表里
 15 # print(ret)      # ['eva', 'egon', 'yuan']
 16 
 17 # ret = re.search('a', 'eva egon yuan')
 18 # if ret:
 19 #     print(ret.group())
 20 # # 从前往后,找到一个就返回,返回的变量需要调用group才能拿到结果
 21 # # 如果没有找到,那么返回None,调用group会报错
 22 
 23 # ret = re.match('[a-z]+', 'eva egon yuan')
 24 # if ret:
 25 #     print(ret.group())
 26 # match是从头开始匹配,如果正则规则从头开始可以匹配上,就返回一个变量。
 27 # 匹配的内容需要用group才能显示
 28 # 如果没匹配上,就返回None,调用group会报错
 29 
 30 # ret = re.split('[ab]', 'abcd')
 31 # # # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
 32 # print(ret)  # ['', '', 'cd']
 33 
 34 # ret = re.sub('\d', 'H', 'eva3egon4yuan4',1)
 35 # 将数字替换成'H',参数1表示只替换1个
 36 # print(ret) #evaHegon4yuan4
 37 
 38 # ret = re.subn('\d', 'H', 'eva3egon4yuan4')
 39 # #将数字替换成'H',返回元组(替换的结果,替换了多少次)
 40 # print(ret)
 41 
 42 # obj = re.compile('\d{3}')
 43 # #将正则表达式编译成为一个正则表达式对象,规则要匹配的是3个数字
 44 # ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串
 45 # print(ret.group())
 46 # ret = obj.search('abcashgjgsdghkash456eeee3wr2') #正则表达式对象调用search,参数为待匹配的字符串
 47 # print(ret.group())  #结果 : 123
 48 
 49 # ret = re.finditer('\d', 'ds3sy4784a')   #finditer返回一个存放匹配结果的迭代器
 50 # print(ret)  # <callable_iterator object at 0x10195f940>
 51 # for i in ret:
 52 #     print(i.group())
 53 
 54 # ------------------元字符--------------------------
 55 
 56 # '.'     默认匹配除\n之外的任意一个字符,若指定flag DOTALL, 则匹配任意字符,包括换行
 57 # '^'     匹配字符开头,若指定flags MULTILINE, 这种也可以匹配上(r"^a", "\nabc\neee", flags=re.MULTILINE)
 58 # '$'     匹配字符结尾,或e.search("foo$", "bfoo\nsdfsf", flags=re.MULTILINE).group()也可以
 59 # '*'     匹配 * 号前的字符0次或多次,re.findall("ab*", "cabb3abcbbac")结果为['abb', 'ab', 'a']
 60 # '+'     匹配前一个字符1次或多次,re.findall("ab+", "ab+cd+abb+bba")结果['ab', 'abb']
 61 # '?'     匹配前一个字符1次或0次
 62 # '{m}'   匹配前一个字符m次
 63 # '{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}", "abb abc abbcbbb")结果 'abb', 'ab', 'abb']
 64 # '|'     匹配 | 左或 | 右的字符,re.search("abc|ABC", "ABCBabcCD").group()结果 'ABC'
 65 # '(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group()结果abcabca456c
 66 #
 67 # '\A'    只从字符开头匹配,re.search("\Aabc", "alexabc")是匹配不到的
 68 # '\Z'    匹配字符结尾,同$
 69 # '\d'    匹配数字0 - 9
 70 # '\D'    匹配非数字
 71 # '\w'    匹配[A - Za - z0 - 9]
 72 # '\W'    匹配非[A - Za - z0 - 9]
 73 # 's'     匹配空白字符、\t、\n、\r, re.search("\s+", "ab\tc1\n3").group()结果'\t'' \
 74 
 75 
 76 # 分组命名
 77 # (?P<name>...) The substring matched by the group is accessible by name.
 78 # obj = re.compile(r'(?P<id>\d+)(?P<name>e+)')  # 从正则表达式匹配的内容每个组起名字
 79 # ret = obj.search('abc123eeee')  # 搜索
 80 # print(ret.group())  # 结果: 123eeee
 81 # print(ret.group("id"))  # 结果: 123 # 获取id组的内容
 82 # print(ret.group("name"))  # 结果: eeee # 获取name组的内容
 83 # (...)与(?:...)
 84 # () 获取匹配的结果
 85 # (?:...) 不获取匹配的结果
 86 # findall
 87 # ret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')
 88 # print(ret)  # ['oldboy']
 89 # ret = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com')
 90 # print(ret)  # ['www.oldboy.com'
 91 # split
 92 # ret=re.split("\d+","eva3egon4yuan")
 93 # print(ret) #结果 : ['eva', 'egon', 'yuan']
 94 # ret=re.split("(\d+)","eva3egon4yuan")
 95 # print(ret) #结果 : ['eva', '3', 'egon', '4', 'yuan']
 96 # # 在匹配部分加上()之后所切出的结果是不同的,
 97 # # 没有()的没有保留所匹配的项,但是有()的却能够保留留了匹配的项,
 98 # # 这个在某些需要保留匹配部分的使用过程是非常重要的。
 99 
100 # 其他(没做深入了解)
101 # (?=...)  Matches if ... matches next, but doesn't consume the string.
102 # (?!...)  Matches if ... doesn't match next.
103 # (?<=...) Matches if preceded by ... (must be fixed length).
104 # (?<!...) Matches if not preceded by ... (must be fixed length).
105 
106 # -----------------------常见问题----------------------------------
107 # 转义的问题
108 # import re
109 # re.findall(r'\\s',r'\s')
110 
111 # 惰性匹配
112 # 量词后面加问号
113 # .*?abc 一直取遇到abc就停
re模块

 


 1 import re
 2 
 3 
 4 def add_sub(equation):
 5     """
 6     计算加减算式,并返回结果
 7     :param equation: 1+2,1-1
 8     :return: float
 9     """
10     # 这里用eval代替了计算加减的函数
11     return eval(equation)
12 
13 
14 def mul_div(equation):
15     """
16     计算加减乘除算式,返回结果。     两端带有括号,里面没有括号
17     :param equation: 包含有加减乘除的式子
18     :return: float
19     """
20     # (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )
21     equation = equation.strip('()')
22     equation = equation.replace('++', '+')
23     equation = equation.replace('+-', '-')
24     equation = equation.replace('-+', '-')
25     equation = equation.replace('--', '+')
26     while True:
27         if '*' in equation or '/' in equation:
28             old = re.search('[\d.]*[*/][-]?[\d.]*', equation)
29             equation = equation.replace(old.group(), str(eval(old.group())))
30         #     这里eval代替了计算乘除的函数,1*2,1/2,1*-1
31         else:
32             return add_sub(equation)
33 
34 
35 def analyze_cal(equation):
36     while True:
37         if '(' in equation:
38             old = re.search('\([^()]*\)', equation)
39             equation = equation.replace(old.group(), str(mul_div(old.group())))
40         else:
41             return mul_div(equation)
42 
43 
44 if __name__ == '__main__':
45     a = '1 - 2 * ( ( 6 0 -3 0  +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
46     a = a.replace(' ', '')
47     print(analyze_cal(a))
计算器-re

 




posted @ 2018-09-28 23:13  写bug的日子  阅读(160)  评论(0编辑  收藏  举报