python-Re正则

正则表达式

https://www.cnblogs.com/qflyue/p/8252528.html

正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。

'''

python 正则 re 用法

字符类:
[ ]匹配括号内多个字符中的任意一个字符
[^ ]表示匹配除了括号内的任意一个字符
- [^0-9]:匹配除了数字的任意一个字符
- [a-z]:匹配任意一个小写字母
- [A-Z]:匹配任意一个大写字母
- [a-zA-Z0-9]:匹配任意一个小写或大写字母或数字

特殊字符类:
- .: 匹配除了\n之外的任意字符; [.\n]
- \d: digit–(数字), 匹配一个数字字符, 等价于[0-9]
- \D: 匹配一个非数字字符, 等价于[^0-9]
- \s: space(广义的空格: 空格, \t, \n, \r), 匹配单个任何的空白字符;
- \S: 匹配除了单个任何的空白字符;
- \w: 字母数字或者下划线, [a-zA-Z0-9_]
- \W: 除了字母数字或者下划线, [^a-zA-Z0-9_]

https://blog.csdn.net/m0_37206112/article/details/87393644
'''

# todo: match 方法
# 从字符串的起始位置开始匹配
# - 如果起始位置没有匹配成功,则返回 None
# - 如果起始位置匹配成功,则返回一个对象,通过 group() 方法来获取匹配的内容
import re

obj = re.match(r'\d', '1wearehappy')
# if obj:
#     print(obj.group()) # 1
# else:
#     print('没有匹配到')

# todo: search 方法
# 会扫描整个字符串,只返回第一个匹配成功的nei
obj1 = re.search(r'\d', '阅读数为2,点赞数是10')
# print(obj1.group()) # 2

# todo: findall 方法
# 会扫描整个字符串,获取匹配的所有内容,返回list
obj2 = re.findall(r'\d+', '阅读数为2,点赞数是10')
# print(obj2) # ['2', '10']

'''
问题描述:
    北美电话的常用格式:(eg: 2703877865)
            前3位: 第一位是区号以2~9开头 , 第2位是0~8, 第三位数字可任意;
            中间三位数字:第一位是交换机号, 以2~9开头, 后面两位任意
            最后四位数字: 数字不做限制;
'''


def is_vaild(pattern, num):
    obj3 = re.search(pattern, num)
    if obj3:
        return ('{}合法'.format(num))
    else:
        return ('{}不合法'.format(num))


if __name__ == '__main__':
    pattern = r'[2-9][0-8][0-9][2-9]\d{6}'
    num = '4651151456'
    num1 = '2652151455'
    is_vaild(pattern, num1)  # 4651151456 合法
    is_vaild(pattern, num)   # 2652151455 不合法 

'''
问题描述:
    指定字符出现的次数
    
     *: 代表前一个字符出现0次或者无限次;    \d*,  .*
     +: 代表前一个字符出现一次或者无限次;     d+
     ?: 代表前一个字符出现1次或者0次;   假设某些字符可省略, 也可以不省略的时候使用,即去贪婪

    
    {m}: 前一个字符出现m次;
    {m,}: 前一个字符至少出现m次;  * == {0,}; + ==={1,}
    {m,n}: 前一个字符出现m次到n次; ? === {0,1}
    
'''
import re

# *: 代表前一个字符出现0次或者无限次;    \d *,.*
print(re.findall(r'\d*', '234')) # ['234', '']
print(re.findall(r'.*', 'hello223%')) # ['hello223%', '']
print(re.findall(r'd*', 'ddhello223%')) # ['dd', '', '', '', '', '', '', '', '', '', '']

#     +: 代表前一个字符出现一次或者无限次;     d+
print(re.findall(r'd+', '')) # []
print(re.findall(r'd+', 'dddderrttt')) # ['dddd']
print(re.findall(r'\d+', '阅读数: 8976 点赞数:900')) # ['8976', '900']

#  ?: 代表前一个字符出现1次或者0次;   假设某些字符可省略, 也可以不省略的时候使用
# 2019-10
print(re.findall(r'\d+-?\d+', '2019-10'))  # ['2019-10']
print(re.findall(r'\d+-?\d+', '201910'))  #  ['201910']
print(re.findall(r'\d{4}-?\d{1,}', '2019-1'))  #  ['2019-1']
print(re.findall(r'\d{4}-?\d{1,2}', '2019-10'))  # ['2019-10']
print(re.findall(r'\d+-?\d+', '201910')) # ['201910']

print(re.findall(r'(\d+?)-(\d+)', '2019-10'))  # [('2019', '10')]

'''
问题描述:
    练习: 匹配一个163邮箱;(xdshcdshvfhdvg@qq.com)  --- 如果想在正则里面匹配真实的. , \.
          xdshcdshvfhdvg(可以由字母数字或者下划线组成, 但是不能以数字或者下划线开头; 位数是6-12之间)


'''
email = 'weldrfgo@163.com'
pattern = r'^[a-zA-Z]\w{5,11}@163.com$'
obj3 = re.search(pattern, email)
# print(obj3.group())

'''
问题描述:
    检查某段给定的文本是否是一个符合需要的URL;
    
    思路:
    1). 检查URL是否以web浏览器普遍采用的通信协议方案开头: http, https, ftp file
    2). 协议后面紧跟 ?/
    3). 协议后面字符任意;

'''


def isUrl(url):
    pattern = r'^(http|https|ftp|file)://.+$'
    obj4 = re.findall(pattern, url)
    if obj4:
        return True
    else:
        return False


if __name__ == '__main__':
    # print(isUrl('fi4le:///tmp'))
    # print(isUrl('http://www.baidu.com'))
    # print(isUrl('https://www.baidu.com'))
    # print(isUrl('ftp://www.baidu.com'))
    pass

'''
问题描述
    北美电话号码的合法性
        1234567890
        123-456-7890
        123.456.7890
        123 456 7890
        (123) 456 7890
        
        统一格式为:
        (123) 456-7890

'''


def is_phone(tel):
    pattern = r'\(?(?P<firstNum>[2-9][0-8]\d)\)?[-\.\s]?(?P<secondNum>[0-8]\d{2})[-\.\s]?(?P<thirdNum>\d{4})'
    obj5 = re.search(pattern, tel)
    if obj5:
        info = obj5.groupdict()
        print(info)
        formatPhone = "(%s) %s-%s" % (info['firstNum'],
                                      info['secondNum'], info['thirdNum'])
        print(formatPhone)
        return True
    return False


# print(is_phone('177-777-7777'))
# print(is_phone('(777) 777 7890'))

'''
问题描述: 
    字符串的替换与分离
'''
import re

s = 'westos is a company'
print(s.replace('westos', 'fentiao'))  # fentiao is a company
# 将westos和company都替换位cat
print(re.sub(r'(westos|company)', 'cat', s))  # cat is a cat

# 将所有的数字替换位0;
s1 = "本次转发数位100, 点赞数为80;"
print(re.sub(r'\d+', '0', s1)) # 本次转发数位0, 点赞数为0;

'''替换 sub 使用函数'''
def addNum(Obj):
    # num是一个字符串
    num = Obj.group()
    # newNum是一个整形数
    newNum = int(num) + 1
    return str(newNum)

# .*?
# 对于所有的数字加1;
print(re.sub(r'\d+', addNum, s1)) # 本次转发数位101, 点赞数为81;

s2 = '1+2=3'
print(re.split(r'[+=]', s2))

'''
问题描述:
    匹配URL地址

'''
import re

url = 'http://www.baidu.com'
pattern = r'^((https|http|ftp|rtsp|mms)?:\/\/)\S+'

# 进行分组的时候, findall方法只返回分组里面的内容;
# print(re.findall(pattern, url))

resObj = re.search(pattern, url)
if resObj:
    # group方法会返回匹配的所有内容;
    print(resObj.group())
    # groups方法返回分组里面的内容;
    print(resObj.groups())

'''
问题描述
    匹配用户名
字符串是否包含中文 []表示匹配方括号的中任意字符,
\u4e00是Unicode中汉字的开始,\u9fa5则是Unicode中汉字的结束
[\w-\u4e00-\u9fa5]+

'''
import re

user = '西部开源123'
pattern = r'[\w\-\u4e00-\u9fa5]+'
print(re.findall(pattern, user))

group 和 groups 的区别

import re
a = "123abc456"
print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group()   #123abc456
print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0)  #123abc456
print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1)  #123
print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2)  #abc
print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3)  #456
print re.search("([0-9]*)([a-z]*)([0-9]*)",a).groups()  #('123', 'abc', '456')

上面正则表达式中的三组括号把匹配结果分成三组

  • group() 同group(0)就是匹配正则表达式整体结果
  • group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3) 列出第三个括号匹配部分。
  • groups()是把所有匹配出来的分组加入元组中
import re
a = "123abc456"
print re.search("[0-9]*[a-z]*[0-9]*",a).group()   #123abc456
print re.search("[0-9]*[a-z]*[0-9]*",a).group(0)  #123abc456
print re.search("[0-9]*[a-z]*[0-9]*",a).groups()  #()

当然正则表达式中没有括号分组,group(1)和groups肯定不对了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值