正则表达式 + 常用示例

前言

        正则表达式,又称规则表达式(英语:Regular Expression,在代码中常简写为regexregexpRE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。

-概念

    - 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑(可以用来做检索,截取或者替换操作)

- 简介

    - 正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,模式描述在搜索文本时要匹配的一个或多个字符串

- 作用

    - 1.给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”)

    - 2.可以通过正则表达式,从字符串中获取我们想要的特定部分。

    - 3.还可以对目标字符串进行替换操作

在Python中需要通过正则表达式对字符串进行匹配的时候, 可以一个模块, 名字为re。

        在文章中若出现了错误的描述还请大家指出!


常用的元字符(特定含义的字符)

        (.):匹配除换行符以外的任意字符

        (\w): 匹配字母或数字或下划线或汉字

        (\s): 匹配任意空白符

        (\d): 匹配数字

        (\b): 匹配单词的开始或结束

        (^): 匹配字符串的开始(在集合字符里[^a]表示非(不匹配)的意思)

        ($): 匹配字符串的结束

注:以上最外层括号只是为了把字符括起来易于查看,无特殊含义


常用的反义字符(多用于查找除某个字符以外其他任意字符均可以的情况)

        (\W): 匹配任意不是字母,数字,下划线,汉字的字符

        (\S): 匹配任意不是空白符的字符

        (\D): 匹配任意非数字的字符

        (\B): 匹配不是单词开头或结束的位置

        ([^x]): 匹配除了x以外的任意字符

        ([^abcd]): 匹配除了abcd以外的任意字符

注:以上最外层括号只是为了把字符括起来易于查看,无特殊含义


常用的限定符(多用于重复匹配次数)

        (*): 重复零次或更多次

        (+): 重复一次或更多次

        (?): 重复零次或一次

        ({n}): 重复n

        ({n,}): 重复n次或更多次

        ({n,m}): 重复nm 

注:以上最外层括号只是为了把字符括起来易于查看,无特殊含义


位置限定符

        (^): 匹配行首的位置

        ($): 匹配行末的位置

        (\<): 匹配单词开头的位置

        (|>): 匹配单词结尾的位置

        (\b): 匹配单词开头或结尾的位置

        (\B): 匹配非单词开头或结尾的位置

注:以上最外层括号只是为了把字符括起来易于查看,无特殊含义


 re模块之match的基本使用:

-  语法:

    - result = re.match(正则表达式,要匹配的字符串)  

-  意义:

    - re.match是用来进行正则匹配检查的方法,如果字符串开头的0个或多个字符匹配正则表达式模式,则返回相应的match对象。如果字符串不匹配模式,返回None(注意不是空字符串"")

    - 匹配对象Macth Object具有group()方法, 用来返回字符串的匹配部分,具有span()方法。返回匹配字符串的位置(元组存储开始,结束位置),具有start(),end()方法,存储匹配数据的开始和结束位置。(也可以通过对象的dir(对象查看对象的方法))

    - 注意:如果想在目标字符串的任意位置查找,需要使用search

-  案例:(mathch vs search)

import re
pattern = 'Hello'
str1 = 'HelloWorld'
v = re.match(pattern,str1)
print(type(v))
print(v)
# print(dir(v))
#使用group可以获取匹配到的数据
# print(v.group())

表示字符

- 语法格式:

    字符 | 功能

   ---|---

    .  | 匹配任意一个字符(除了\n)

    [ ] | 匹配列表中的字符

    \d | 匹配数字,即0-9

    \D | 匹配非数字

    \s | 匹配空白、即空格(\n,\t)

    \S | 匹配非空格

    \w | 匹配单词字符,即a-z,A-Z,0-9,_

    \W | 匹配非单词字符

使用示例:

示例1:

    import re
    v = re.match('.','a')
    v = re.match('.','1')
    v = re.match('.','_')
    #返回None
    v = re.match('.','\n')
    print(v)
    v = re.match('\d','1')
    print(v)
    v = re.match('\D','a1')
    print(v)
    v = re.match('\s',' ')
    v = re.match('\s','\n')
    v = re.match('\s','\t')
    print(v)
    #非空格
    v = re.match('\S',' ')
    print(v)
    v = re.match('\w','a')
    v = re.match('\w','A')
    v = re.match('\w','1')
    v = re.match('\w','_')
    print(v)
    
    v = re.match('\W','a')
    v = re.match('\W','A')
    v = re.match('\W','1')
    v = re.match('\W','_')
    print(v)
    
    v = re.match('\w\W','1a')
    print(v)

示例2:"[ ]"的使用

    #手机号匹配问题
    v = re.match('\d\d\d\d\d\d\d\d\d\d\d','13312341234')
    v = re.match('1[35789]\d\d\d\d\d\d\d\d\d','12312341234')
    #\d == [0-9]
    #\D == [^0-9]
    #\w == [a-zA-Z0-9_]
    #\W == [^a-zA-Z0-9_]
    print(v)

表示数量(匹配多个字符)

- 语法

     字符 | 功能

    ---|---

    *  | 匹配前一个字符出现0次或者无限次(可有可无)

    + | 匹配前一个字符出现1次或者无限次(至少有1次)

    ? | 匹配前一个字符串出现1次或者0次(要么1次要么没有)

    {m} | 匹配前一个字符出现m次

    {m,} | 匹配前一个字符至少出现m次

    {m,n} | 匹配前一个字符出现m到n次

- 代码验证:

    import re
    pattern = '\d*'
    #注意,这时候表示数字可有可无,如果没有的话,则匹配''
    v = re.match(pattern,'abc123')
    print(v)
    print('11111111111111')
    pattern = '\d+'
    v = re.match(pattern,'abc123')
    print(v)
    v = re.match(pattern,'123abc123')
    print(v)
    pattern = '\d?'
    v = re.match(pattern,'123abc')
    print(v)
    pattern = '\d{3}'
    v = re.match(pattern,'1234abc')
    print(v)
    pattern = '\d{3,}'
    v = re.match(pattern,'1234abc')
    print(v)
    
    pattern = '\d{3,6}'
    v = re.match(pattern,'1235674abc')
    print(v)

- 使用示例1 *

    - 匹配出一个字符串首字母为大写字符,后边都是小写字符,这些小写字母可有可无

pattern = '[A-Z][a-z]*'
v = re.match(pattern,'Hello')
print(v)

- 使用示例2 +

    - 匹配出有效的变量名

#有效的变量名  开头为字母
pattern = '[a-zA-Z_]+[\w_]*'
v = re.match(pattern,'1name123')
print(v)

- 使用示例3 ?

    - 匹配出1-99之间的数字

pattern = '[1-9][0-9]?'
v = re.match(pattern,'09')
print(v)
v = re.match(pattern,'33')
print(v)
v = re.match(pattern,'7')
print(v)

- 使用示例4 {m}

    - 匹配出一个随机密码8-20位以内

pattern = '[a-zA-Z0-9_]{8,20}'
v = re.match(pattern,'dafadf22432adfag')
print(v)

原始字符串

- 概述:

    - Python中字符串前边加上 r 表示原生字符串

- 示例:

    - 字符串中的使用

        - 字符串s = '\n123' 与 s = r'\n123'

    - 正则中使用

 s = '\n123'

print(s)

s = r'\n123'

print(s)

# s = '\\n123'

# print(s)

# pattern = '\\\\n\d{3,}'

pattern = r'\\n\d{3,}'

v = re.match(pattern,s)

print(v)

表示边界

- 语法及意义:

    字符 | 功能

    ---|---

    ^ | 匹配字符串开头

    $ | 匹配字符串结尾

    \b | 匹配一个单词的边界

    \B | 匹配非单词的边界

- 案例:

    - 使用示例1 匹配QQ邮箱 &  

#匹配qq邮箱,  5-10位

pattern = '[\d]{5,10}@qq.com'

#必须限制结尾的

# pattern = '[1-9]\d{4,9}@qq.com$'

#正确的地址

v = re.match(pattern,'12345@qq.com')

#未限制结尾的前提下使用不正确的地址

# v = re.match(pattern,'12345@qq.comabc')

print(v)

 

 - 使用示例2 \b 匹配单词边界

pattern = r'.*\bab'
#ab左边界的情况
v = re.match(pattern,'123 abr')
print(v)

pattern = r'.*ab\b'
#ab为右边界的情况
v = re.match(pattern,'wab')
print(v)

 - 使用示例3 \B 匹配非单词边界

#ab不为左边界
pattern = r'.*\Bab'
v = re.match(pattern,'123 abr')
print(v)
#ab不为右边界
pattern = r'.*ab\B'
v = re.match(pattern,'wab')
print(v)

匹配分组

- 语法

     字符 | 功能

        ---|---

        丨  | 匹配左右任意一个表达式

        (ab) | 将括号中的字符作为一个分组

        \num | 引用分组num匹配到的字符串

        (?p<name>) | 分别起组名

        (?p=name) | 引用别名为name分组匹配到的字符串

- 示例1 |的使用

    - 匹配0-100之间所有的数字

pattern = '[1-9]?\d$|100$'
v = re.match(pattern,'0')
print(v)
v = re.match(pattern,'10')
print(v)
v = re.match(pattern,'100')
print(v)
v = re.match(pattern,'99')
print(v)
v = re.match(pattern,'200')
print(v)

- 示例2 ()的使用

    - 匹配座机号码

#匹配一个固定电话号码  010-66668888
pattern = r'(\d+)-(\d{5,8}$)'
v = re.match(pattern,'010-66668888')
print(v)
print(v.group())
print(v.group(1))
print(v.group(2))
print(v.groups())
print(v.groups()[0])
print(v.groups()[1])

- 示例3 \num 的使用

    - 匹配出网页标签内的数据

s = '<html><title>我是标题</title></html>'
#优化前
# pattern = r'<.+><.+>.+</.+></.+>'
#优化后 可以使用分组  \2 表示引用第2个分组  \1表示引用第1个分组
pattern = r'<(.+)><(.+)>.+</\2></\1>'
v = re.match(pattern,s)
print(v)

 - 示例4 ?P<要起的别名>  (?P=起好的别名)

s = '<html><h1>我是一号字体</h1></html>'
# pattern = r'<(.+)><(.+)>.+</\2></\1>'
#如果分组比较多的话,数起来比较麻烦,可以使用起别名的方法?P<要起的名字>  
以及使用别名(?P=之前起的别名)
pattern = r'<(?P<key1>.+)><(?P<key2>.+)>.+</(?P=key2)></(?P=key1)>'
v = re.match(pattern,s)
print(v)

re模块的高级用法

- search

    - 作用:

        - 扫描字符串,查找正则表达式模式产生匹配的第一个位置,并返回相应的匹配对象。如果字符串中没有与模式匹配的位置,则返回None;

    - 用法:

import re
v = re.match('\d+','阅读次数为 9999 次')
print(v)
v1 = re.search('\d+','阅读次数为 999 次')
print(v1)

- findall

    - 作用

      - 从左到右扫描字符串,并按照找到的顺序返回匹配。如果模式中有一个或多个组,返回组表

    - 用法

list1 = re.findall(r'\d+',"阅读次数C:129 Python:999 C++:99")
print(list1)

- sub

    - 作用:

        - 返回通过替换repl替换字符串中最左边不重叠的模式出现而得到的字符串。如果没有找到模式,则返回字符串不变

    - 用法1: 直接替换

#将目标字符串中所有的字符'c'替换成'a'
s = re.sub(r'a','c',"adfjalkdfkdasf")
print(s)

 - 用法2:  使用函数(可以运算)替换

def replace(result):
print(type(result))
print(type(result.group()))
print(result.group())
r = int(result.group())+ 1
return str(r)
#将目标字符串中所有的阅读次数+1
v = re.sub(r'\d+',replace,"阅读次数C:129 Python:999 C++:99")
print(v)

- split

    - 作用:

        - 通过指定模式拆分字符串

    - 用法1:

        - 按指定的格式拆分字符串

v = re.split(r',|-|:','Tom:HelloWorld,james-bond')
print(v)

贪婪模式和非贪婪

- 什么是贪婪模式?

    - Python里数量词默认是贪婪的, 总是尝试匹配尽可能多的字符

- 什么是非贪婪

    - 与贪婪相反,总是尝试匹配尽可能少的字符,可以使用"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪

- 使用示例1:

#贪婪模式,.+中的'.'会尽量多的匹配
# v = re.match(r'(.+)(\d+-\d+-\d+)','This is my tel:133-1234-1234')
v = re.match(r'(.+?)(\d+-\d+-\d+)','This is my tel:133-1234-1234')
print(v.group(1))
print(v.group(2))

 - 使用示例2

#贪婪模式
v= re.match(r'abc(\d+)','abc123')
print(v.group(1))
#非贪婪模式
v= re.match(r'abc(\d+?)','abc123')
print(v.group(1))

常见的一些正则表达式:

1.数字:^[0-9]*$

2.n-m位之间的数字:^\d{n,m}$

3.有1~3位小数的正实数: ^[0-9]+(.[0-9]{1,3})?$

4.正数,负数,小数: ^(\+|\-)?\d+(\.\d+)?$

5.正整数: ^\d+$ 或 ^[1-9]\d*|0$

6.负整数: ^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$

7.长度为1-10位的所有字符: ^.{1,10}$

8.有数字和字母组成的字符串: ^[a-zA-Z0-9]$

9.合法账号(字母开头,内容包括字母,数字,下划线,长度在6-16位):

   ^[a-zA-Z][a-zA-Z0-9_]{5,115}$

10.密码(字母开头,只能包含字母,数字,下划线): ^[a-zA-Z]\w{5,17}$

11.Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$

12.网站域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?

13.URL网址:^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$

14.QQ号:[1-9][0-9]{4,8} (腾讯QQ号从10000开始,目前最长为10)

15.中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)

16.IP地址:\d+\.\d+\.\d+\.\d+ (提取IP地址时有用)

17.身份证号码(15位,18位数字): ^\d{15}|\d{18}$


  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NGIWS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值