正则理解与总结笔记

正则理解与总结笔记

written by Marshal Zheng

一、正则语法
  • 元字符
    • \b:匹配单词的开始或者结束
    • \d:匹配数字
    • \s:匹配任意不可见字符(空格、换行符、制表符等)
    • \w:匹配任意Unicode字符集,包括字母、数字、下换线、汉字等;匹配出换行符’\n’之外的任意字符
    • ^或者\A:匹配字符串或行的起始位置
    • $或者\Z:匹配字符串或行的结束位置
  • 限定词
    • *:重复0次或更多次
    • +:重复1次或者更多次
    • ?:重复0次或者1次
    • {n}:重复n次
    • {n,}:重复n次或更多次
    • {n,m}:重复n到m次
  • 反义词
    • \B:匹配非单词的开始或结束
    • \D:匹配非数字
    • \S:匹配任意可见字符
    • \W:匹配任意非Unicode字符集
    • [^abc]:匹配a、b、c以外的任意字符
  • 字符族
    • [abc]:a、b或者c
    • [a-zA-z]:a到z或者A到Z
    • [a-d[m-p]]:a到d或者m到p,并集
    • [a-z&&[def]]:d、e或者f,交集
    • [a-z&&[ ^bc]]:a到z,除了b,c,交集减去
    • [a-z&&[ ^m-p]]:a到z,减去m到p,交集减去
  • python修饰符
    • re.A = 匹配ASCII字符类,影响\w,\W,\B,\b,\D,\d
    • re.I = 忽略大小写
    • re.L = 做本地化识别匹配
    • re.M = 多行匹配,影响^ or $
    • re.S =使 . 匹配包括换行符在内的所有字符
    • re.U = 匹配Unicod字符集,与re.A相对,默认设置
    • re.X = 忽略空格和#后面的注释以获得看起来更易懂的正则
二、实例
实例1
s = '123abc你好'
re.search('\d+', s).group()
re.search('\w+', s).group()

结果

123
123abc你好
实例2:re.A

修饰符 A 使 \w 只匹配 ASCII 字符,\W 匹配非 ASCII 字符。

s = '123abc你好'
re.search('\w+', s, re.A).group()
re.search('\W+', s, re.A).group()

结果

123abc
你好

\d\D全角和半角

s = '0123456789'    # 全角数字
re.search('\d+', s, re.U).group()

实例2:re.M

s = 'aaa\r\nbbb\r\nccc'

re.findall('^[\s\w]*?$', s)
re.findall('^[\s\w]*?$', s, re.M)

结果

['aaa\r\nbbb\r\nccc']        # 单行模式
['aaa\r', 'bbb\r', 'ccc']    # 多行模式

实例3:re.S

s = 'aaa\r\nbbb\r\nccc'

re.findall('^.*', s)
re.findall('^.*', s, re.S)

结果

['aaa\r']
['aaa\r\nbbb\r\nccc']

实例4:re.X

rc = re.compile(r"""
\d+ # 匹配数字
# 和字母
[a-zA-Z]+
""", re.X)
rc.search('123abc').group()

结果

123abc
三、贪婪和懒惰
贪婪

尽可能多的匹配

*+{n,} 这些表达式属于贪婪;

懒惰

尽可能少的匹配

*?+?{n,}? 这些表达式就是懒惰(在贪婪的基础上加上 ?)。

实例
s = 'aabab'
re.search('a.*b', s).group()    # 这就是贪婪
re.search('a.*?b', s).group()   # 这就是懒惰

结果

aabab
aab
四、自动捕获
(exp)匹配exp,并捕获文本到自动命名的组里
(?Pexp)匹配exp,并捕获文本到名称为 name 的组里
(?:exp)匹配exp,不捕获匹配的文本,也不给此分组分配组号
(?P=name)匹配之前由名为 name 的组匹配的文本

注意:在其他语言或者网上的一些正则工具中,分组命名的语法是 (?<name>exp)(?'name'exp) ,但在 Python 里,这样写会报错:This named group syntax is not supported in this regex dialect。Python 中正确的写法是:(?P<name>exp)

实例1:

s = '姓名:张三;性别:男;电话:138123456789'
m = re.search('姓名[::](\w+).*?电话[::](\d{11})', s)
if m:
    name = m.group(1)
    phone = m.group(2)
    print(f'name:{name}, phone:{phone}')

结果:

name:张三, phone:13812345678

实例2:

s = '''
<name>张三</name>
<age>30</age>
<phone>138123456789</phone>
'''

pattern = r'<(?P<name>.*?)>(.*?)</(?P=name)>'
It = re.findall(pattern, s)

结果

[('name', '张三'), ('age', '30'), ('phone', '138123456789')]
五、零宽断言
(?=exp)匹配exp前面的位置
(?<=exp)匹配exp后面的位置
(?!exp)匹配后面跟的不是exp的位置
(?<!exp)匹配前面不是exp的位置

python中前项界定的表达式必须是定长的

结果

(?<=aaa)        # 正确
(?<=aaa|bbb)    # 正确
(?<=aaa|bb)     # 错误
(?<=\d+)        # 错误
(?<=\d{3})      # 正确
六、findall
  • 如果没有分组,则返回整条正则匹配结果的列表;
  • 如果有 1 个分组,则返回分组匹配到的结果的列表;
  • 如果有多个分组,则返回分组匹配到的结果的元组的列表。

实例

s = 'aaa123bbb456ccc'

re.findall('[a-z]+\d+', s)          # 不包含分组
re.findall('[a-z]+(\d+)', s)        # 包含一个分组
re.findall('([a-z]+(\d+))', s)      # 包含多个分组
re.findall('(?:[a-z]+(\d+))', s)    # ?: 不捕获分组匹配结果

结果

['aaa123', 'bbb456']
['123', '456']
[('aaa123', '123'), ('bbb456', '456')]
['123', '456']

感谢网上正则文章的指导,本文还有很多不完善的地方,将在以后学习过程中添加。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值