11_正则

正则表达式

正则表达式是一个特殊的字符序列,帮助检查一个字符串是否与某种模式匹配。

用途

  • 检测一个输入的字符串是否合法 ---- Web开发项目 表单验证
  • 用户输入内容的时候,提前做检测
  • 能够提高程序的效率,减轻服务器的压力
  • 从大文件中找到所有符合规则的内容
  • 能够高效的从一大段文字中快速找到符合规则的内容

1、元字符和量词

元字符 描述
  • ^ 匹配字符串的开头

  • $ 匹配字符串的末尾。

  • . 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。

  • [().*+?] 这些内容在字符组中会取消他们的特殊意义

  • [...] 用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'

  • [^...] 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。

  • \s 匹配任意空白字符,相当于[\t\n\r\f](制表符、回车、空格)。

  • \S 匹配任意非空字符

  • \d 匹配任意数字,等价于 [0-9]。

  • \D 匹配任意非数字

  • \w 匹配数字字母下划线

  • \W 匹配非数字字母下划线

  • \A 匹配字符串开始

  • \Z 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。

  • \z 匹配字符串结束

  • \G 匹配最后匹配完成的位置。

  • \b 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。

  • \B 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。

  • \n, \t, 等。 匹配一个换行符。匹配一个制表符, 等

  • \1...\9 匹配第n个分组的内容。

  • \10 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。

  • a| b 匹配a或b,匹配a成功就不匹配b,如果a、b相似,将长的写在前面

  • (re) 匹配括号内的表达式,也表示一个组

  • (?: re) 类似 (...), 但是不表示一个组(取消这个组的优先显示)

  • (?imx) 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。

  • (?-imx) 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。

  • (?imx: re) 在括号中使用i, m, 或 x 可选标志

  • (?-imx: re) 在括号中不使用i, m, 或 x 可选标志

  • (?#...) 注释.

  • (?= re) 前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。

  • (?! re) 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功。

  • (?> re) 匹配的独立模式,省去回溯。

量词 描述
  • { n} 匹配n个前面表达式。例如,"o{2}"不能匹配"Bob"中的"o",但是能匹配"food"中的两个o。

  • { n,} 精确匹配n个前面表达式。例如,"o{2,}"不能匹配"Bob"中的"o",但能匹配"foooood"中的所有o。"o{1,}"等价于"o+"。"o{0,}"则等价于"o*"。

  • { n, m} 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式

  • * 匹配0个或多个的表达式。
  • + 匹配1个或多个的表达式。
  • ? 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
贪婪匹配

​ .*?x 表示匹配任意字符,任意多次数,遇到最后一个x才停下来

非贪婪匹配

​ .*?x 表示匹配任意字符,任意多次数,遇到第一个x才停下来

2、re模块

re 模块使 Python 语言拥有全部的正则表达式功能。
compile 函数

​ 根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。
​ re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。

a、用途:

​ 标签匹配
​ 用户输入匹配

  • match() 从开头匹配一次
  • search() 只匹配一次
  • findall() 查找所有
  • sub() 替换
  • split() 切割

b、方法:

re.compile(正则) 方法

​ 加入同一个正则表达式要被使用多次,节省了多次解析同一个正则表达式的时间 (节省解析时间)

ret = re.compile(r'\d+')
res1 = ret.search('116afafe1561f')
res2 = ret.findall('116afafe1561f')
print(res1.group())  # 116
print(res2)  # ['116', '1561']

re.finditer() 方法

返回一个迭代器,通过迭代取代一个变量,通过group提取(节省空间)

ret = re.finditer(r'\d+', '123afdsfa445')
print(ret)  # <callable_iterator object at 0x0000018DB9A9B8C8>
for i in ret:
    print(i.group())

# 输出
#     123
#     445

既节省时间,有节省空间
ret = re.compile(r'\d+')
res = ret.finditer('45fd6afd5a6f')
for r in res:
    print(r.group())

输出:
    45
    6
    5
    6

re.findall方法

​ 查找所有,按照完整的正则进行匹配,只是显示括号里匹配到的内容

re.search方法

​ 扫描整个字符串并返回第一个成功的匹配。显示匹配到的第一个内容,可以通过group方法传参数来获取具体元组中的内容

函数语法

​ re.search(pattern, string, flags=0)

re.match函数

​ re.match 字符串的起始位置匹配一个模式,起始位置匹配不成功,match()就返回none。

函数语法

​ re.match(pattern, string, flags=0)

group(num) 或 groups() 匹配对象函数来获取匹配表达式。

匹配对象方法 描述

  • group(num=0) 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
  • groups() 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。

re.match与re.search的区别

​ re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。

re.sub函数

​ 替换字符串:通过正则表达式匹配的内容来进行替换

msg = "java:90 python:89 C++:99 VF:89"
result = re.sub(r'\d+','100',msg) # 将所有数字变成100
print(result)
# 利用函数将字符串中的数字+1
def func(temp):
    num = int(temp.group())+1
    return str(num)
result = re.sub(r'\d+',func,msg)

re.subn函数

​ 替换,在sub的基础上返回一个元组,第一个是替换结果,第二个是替换次数

re.split 切割

result = re.split(r'[:\s]',msg) # 将分割的内容保存在字符串中
print(result)

使用()进行字符串分组

# 判断邮箱地址 163 或者 126 或者 qq
emails = '[email protected]'

res5 = re.match(r'\w{6,12}@(aa|163|126)\.(com|cn)$',emails) # 新版
print(res5)

# 分组提取区号 010-12121321
num = '010-5645616'
result = re.match(r'(\d{3}|\d{4})-(\d{7})',num) # 一个()代表一组,
print(result)
print(result.group())
print(result.group(1)) # 用group(1-9)提取数组
print(result.group(2))

# 提取标签里的内容
# <html>hello</html>
# <h1>world</h1>

msg = '<html>hello</html>'
msg1 = '<h1>world</h1>'
result = re.match(r'<\w+>(.+)</\w+>',msg1) # 前后标签内容不一样时也会匹配<html>adf</h1>
print(result)
print(result.group(1))

使用数字 \1...\9

msg2 = '<h1>world</h1>'
msg3 = '<html><h1>world</h1></html>'
result = re.match(r'<(\w+)>(.+)</\1>$',msg2)
print(result)
print(result.group(2))
result = re.match(r'<(\w+)><(\w+)>(.+)</\2></\1>$',msg3) # 太长使用数字容易混淆,用起名方式
print(result)
print(result.group(3))

正则起名字的方式 (?P 正则表达式) 引用:(?P=name)

msg3 = '<html><h1>world</h1></html>'
result = re.match(r'<(?P<name>\w+)><(?P<name1>\w+)>(.+)</(?P=name1)></(?P=name)>',msg3)
re.group(name1)

猜你喜欢

转载自www.cnblogs.com/q121211z/p/13383937.html