15-正则表达式
正则表达式三个方法
-
Regular Expression
- 匹配有规则的字符串
-
import re
-
re.match()
- 匹配字符串是否以指定正则表达式开头
- res = re.match('\d+', '123456') # object,返回对象或者None
- 匹配字符串是否以指定正则表达式开头
-
re.search()
-
匹配字符串是否包含表达式
-
res2 = re.search('oog', 'google') # object,返回对象或者None
-
# re.I忽略大小写 res2 = re.search('GOO', 'google', re.I) # object
-
-
-
-
re.findall()
- 获取所有匹配的子字符串,返回的是列表
- res3 = re.findall('goo', 'google google google') # ['goo', 'goo', 'goo'],如果匹配不到则返回空列表
- 获取所有匹配的子字符串,返回的是列表
匹配单个字符
- .
- . 表示匹配任意单个字符,除了换行\n
- 注意r''只能消除字符串中的语义,不影响正则的语义,因此要匹配点(.),需要在点前加\
- print(re.search('go.gle', 'go\ngle', re.S)) # 对象
- re.S可以让 . 匹配\n
- []
- 表示匹配单个字符的范围
- [abc]:匹配a或b或c
- [a-zA-Z0-9_]:匹配数字字母下划线
- print(re.search('go[a-zA-Z0-9_]gle', 'go_gle')) # 对象
- \d
- 表示数字,等价于[0-9]
- \D :表示非数字,等价于[^0-9]
- print(re.search('go\dgle', 'go8gle')) # 对象
- \w
- 表示数字字母下划线,等价于[a-zA-Z0-9_]
- \W表示非数字字母下划线,等价于[^a-zA-Z0-9_]
- print(re.search('go\wgle', 'go8gle')) # 对象
- \s
- 表示空格 或换行\n 或 制表符\t 或 换页符\f 回车符\r
- \S表示非(空格 或换行\n 或 制表符\t 或 换页符\f 回车符\r)
- print(re.search('go\Sgle', 'go gle')) # None
表示数量的符号
- ?
- 表示前面的字符可以出现0次或1次
- print(re.findall('go?gle', 'google')) # [] # 非贪婪(最多匹配一个)
- 表示前面的字符可以出现0次或1次
- +
- 表示前面的字符可以出现1次或多次
- print(re.findall('go+gle', 'gooogle')) # ['gooogle'] # 贪婪(尽量多个匹配)
- *
- *表示前面的字符可以出现0次或多次
- print(re.findall('g.*gle', 'g123abc,.;gle')) # ['g123abc,.;gle']
- *表示前面的字符可以出现0次或多次
- {}
- 表示前面字符出现的次数范围
- {3} :表示前面字符出现3次
- {2, 5} :表示从2次~5次之间
-
- print(re.findall('go{2,5}gle', 'gooogle')) # ['gooogle'],2和5之间不能加空格 # 贪婪
边界符号(锚字符)
- ^
- ^ :开头匹配
- $
- $ :结尾匹配
- ^$
- ^$ :完全匹配:除了正则中的字符串以外,不可以有其他多余的字符
- 其他边界字符串
- \A\Z
- 与^$作用基本一致
- 区别
- print(re.findall('^#', '#google\n#baidu\n#360', re.M)) # ['#', '#', '#']
- print(re.findall('\A#', '#google\n#baidu\n#360', re.M)) # ['#']
- re.M
- re.M: 换行模式
- \A\Z
- \b
- 以单词结尾
- \B以非单词结尾
- chinesePattern = "[\u4e00-\u9fa5]+"
分组和捕获
-
分组
-
()
-
() :表示整体,还可以表示分组
-
s = '0755-88888888' pattern = '(\d{4})-(\d{8})' # pattern = '\d{4}-\d{8}' res = re.search(pattern, s)
-
-
print(res.group()) # '0755-88888888'
-
print(res.group(0)) # '0755-88888888'
-
print(res.group(1)) # '0755', 第一个分组(第一个括号的内容)
-
print(res.group(2)) # '88888888', 第二个分组(第二个括号的内容)
-
print(res.groups()) # ('0755', '88888888'),获取所有分组
-
-
-
捕获
-
用findall(),返回列表
-
pattern = r'(\d+)万到(\d+)万卢比' res = re.findall(pattern, s) # 捕获()里面的 print(res) # [('15', '40')]
-
别名
-
?P<别名>
-
pattern = r'(?P<start>\d+)万到(?P<end>\d+)万卢比' res = re.search(pattern, s) print(res.group('end')) # 40 print(res.group('start')) # 15
-
-
-
-
-
编译正则
-
编译正则:创建一个正则表达式对象,效率更高
-
# re.compile() pattern = re.compile(r'(\d+)万到(\d+)万卢比') res = pattern.findall(s) print(res) # [('15', '40')]
-
-
-
非捕获性分组
-
?:
-
pattern = r'(\d+)万到(?:\d+)万卢比' res = re.findall(pattern, s) print(res) # ['15']
-
-
其他正则函数
-
re.finditer
-
匹配后的结果=>迭代器
-
res = re.finditer(r'\d+', '123abc456def678') print(res) # 迭代器,<callable_iterator object at 0x0000026B6059F7C8> for i in res: # print(i) print(i.group(), i.span()) ''' 123 (0, 3) 456 (6, 9) 678 (12, 15) '''
-
-
-
re.split
-
分割/拆分
-
s = 'hello world' print(re.split(r'l|\s', s)) # ['he', '', 'o', 'wor', 'd'] print(re.split(r'l|o', s)) # ['he', '', '', ' w', 'r', 'd']
-
|表示或者
-
-
-
re.sub
-
替换
-
s = 'today is a good day today is a nice day' print(re.sub(r'\s', '-', s)) # today-is-a-good-day-today-is-a-nice-day print(re.subn(r'\s', '-', s)) # ('today-is-a-good-day-today-is-a-nice-day', 9)
-
-
补充
- 空白行
- \n\s*\r
- 前后空白字符串
- ^\s*|\s*$
- 零宽断言
- ?=exp
- 断言当前位置后面能匹配exp
- ?<=exp
- 断言当前位置前面能匹配exp
- ?!exp
- 断言当前位置后面不能匹配exp
- ?<!exp
- 断言当前位置前面不能匹配exp
- ?=exp