正则表达式

正则表达式是一个通用概念,不管你使用的编程语言是Python还是Java亦或C#。python里实现正则的模块是re,使用前需导入。

一、语法

1.基本元素

正则表达式元字符及其含义
  字符                                            含义
      .匹配除换行符以外任意字符
     \w字母、数字、下划线、汉字
     \W排除\w
     \d数字
     \D排除\d,即非数字
     \s空白符
     \S非空白符        
     ^字符串的开始
     $字符串的结束
     \b单词的开始或结束
     \B非单词边界
     []字符集
    [^]排除集
     |
     \转义
     ()分组

2.数量限定符

   符号说明
     ?匹配零次或一次
     +一次或多次
     *零次或多次
    {n}n次
    {n,}至少n次
  {m, n}至少m次,至多n次

二、re模块

1.从开头进行匹配——re.match

相当于你的正则表达式要和整个字符串匹配,遇到不匹配的字符直接返回None。

import re
s = '23ab45cd'
p = r'^\d+'
res = re.match(p, s)
if res:
    print('匹配开始位置:', res.start())
    print('匹配结束位置:', res.end())
    print('匹配结果:', res.group())

# 输出:匹配开始位置: 0
       匹配结束位置: 2
       匹配结果: 23

2.匹配第一个符合的字符串片段——re.serach

搜索整个字符串,直到遇到第一个匹配的值。如果没有匹配值,返回None。

s = '@23ab45cd'
p = r'\d+'
res = re.search(p, s)
if res:
    print('匹配结果:', res.group())

# 输出:匹配结果: 23

3.匹配所有符合的值——re.findall

返回所有的匹配结果,以列表形式返回。

s = '@23ab45cd'
p = r'\d+'
res = re.findall(p, s)
if res:
    print('匹配结果:', res)

# 输出:匹配结果: ['23', '45']

4.使用正则替换字符串——re.sub

简单理解就是替换符合表达式的一类字符。

# 将数字替换为'xx'
s = '@23ab45cd'
p = r'\d+'
res = re.sub(p, 'xx', s)
print('替换结果:', res)


# 输出:替换结果: @xxabxxcd

5.使用正则分割字符串——re.split

即分割符是符合表达式的一类字符

# 以数字作为分隔符
s = '@23ab45cd'
p = r'\d+'
res = re.split(p, s)
print('分割结果:', res)


# 输出:分割结果: ['@', 'ab', 'cd']

6、标志——flag

常用标志及含义
        标志含义
A或ASCII只进行ASCLL匹配
I或IGNORECASE忽略大小写
M或MULTILINE将^和$作用于每一行的开头和结尾(针对多行)
S或DOTALL."将匹配所有字符,包括换行符
X或VERBOSE忽略模式字符串中未转义的空格和注释

s = '我am a 码农'
p = r'\w+'
# 早期ASCLL编码只包含英文字母和一些符号
res = re.findall(p, s, re.A)
# python3采用Unicode编码,中英法等都会被认为是“字母”,即都能被\w匹配
res2 = re.findall(p, s)
print('只匹配ASCLL结果:', res)
print('默认匹配结果:', res2)


# 输出:只匹配ASCLL结果: ['am', 'a']
        默认匹配结果: ['我am', 'a', '码农']

三、综合使用

1.字符串定位符^$和单词首尾定位\b的区别

字符串就是一对引号里的内容,^和$默认只匹配整个字符串的开始和结尾,如果使用标志M,则会匹配多行字符串每一行的开始和结尾。

s = '123@abc_111.com\n456@abc_111.com'
p = r'^.+$'
# 相当于换行符的前后会被认为是字符串的首尾
res = re.findall(p, s, re.M)
# 默认作用于整个字符串首尾,首尾之间有换行符,因此"."不能匹配
res2 = re.findall(p, s)
print('匹配多行结果:', res)
print('默认匹配结果:', res2)


# 输出:匹配多行结果: ['123@abc_111.com', '456@abc_111.com']
        默认匹配结果: []

单词的定义可以理解为\w的范围(字母数字下划线)。\b则去匹配逗号分号等各种符号。

s = '123@abc_111.com 456@abc_111.com'
p = r'\b\w+\b'
res = re.findall(p, s)
print('匹配结果:', res)

# 可以理解为@.和空格被作为边界
# 输出:匹配结果: ['123', 'abc_111', 'com', '456', 'abc_111', 'com']

2.()和"|"的用法

# 这里并非完整实现邮箱匹配,仅限制开头是数字+@
# @后面接2个字母或3个数字
s = '123@qq.com\n123@163.com'
p = r'^\d+@([a-z]{2})|(\d{3}).*$'
res = re.findall(p, s, re.M)
print('匹配结果:', res)


# 当匹配123@qq.com时,一个分组匹配成功,结果是'qq';第二个分组匹配失败,因此结果是空字符。
# 还有一个要点,返回结果并不是完整的邮箱,只返回分组内匹配成功的元素
# 输出:匹配结果: [('qq', ''), ('', '163')]

如果想得到完整的邮箱,可以将你想要的信息再通过一个()包含进去即可

s = '123@qq.com\n123@163.com'
p = r'^(\d+@([a-z]{2})|(\d{3}).*)$'
res = re.findall(p, s, re.M)
print('匹配结果:', res)


# 输出
匹配结果: [('123@qq.com', '', '123'), ('123@163.com', '', '123')]

3.()\数字

如()()\2,表示(第一组)(第二组)(第二组),即\2指代第二组

s = '123@qq.com_qqcom'
# 表示任意长度>=3的子字符串为一组,后面可能接其他元素,
# 再后面是任意长度>=2的子串作为第二组,然后重复第一组
p = r'(.{3,}).*(.{2,})\1'
res = re.findall(p, s)
print('匹配结果:', res)


# 输出: 匹配结果: [('com', 'qq')]

4.转义

正则表达式中pattern是作为模式字符串,因模式字符串需要使用大量反斜线和特殊字符,为了避免和转义字符混淆,一般在其前面加一个r或R。

print(r'不进行\n转义')
print('进行\n转义')


# 输出:不进行\n转义
       进行
       转义

5.贪婪和非贪婪模式

贪婪模式:尽可能多的匹配,包括+,  ?, * , {n,},   {n,M}

非贪婪模式:尽可能少的匹配,在贪婪模式的基础上加一个"?",如+?, ??, *?

s = 'abc123ABC123'
p = r'[a-z]+'
p2 = r'[a-z]+?'
res = re.match(p, s)
res2 = re.match(p2, s)
print('贪婪匹配结果:', res.group())
print('非贪婪匹配结果:', res2.group())


# 输出:贪婪匹配结果: abc
        非贪婪匹配结果: a

6.匹配中文

s = 'abc123中文123汉字'
p = r'[\u4e00-\u9fa5]+'
res = re.findall(p, s)
print('匹配结果:', res)


# 输出:匹配结果: ['中文', '汉字']

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值