re模块中的两个函数:
re.match()总是从字符串的开始位置匹配, 所以很多情况下能够匹配的概率不大.
re.search()是在字符串中搜索正则表达式模式, 任何位置都可以. 返回的是第一次出现的匹配情况(因为正则字符串中可能会多处匹配)
re.match()和re.search()的区别:
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
详细如下:
简介、匹配单个、多个、位置、分组
一、正则简介
Regular Expression,又称规则表达式
定义:字符串的匹配模式;用特定字符组成“规则字符串”。
作用:检查一个串是否含有某种数据、将匹配的数据替换 或者取出
特点: 功能强大;使用灵活。
使用流程:
1、导入re模块
import re
2、使用match方法进行匹配操作
ret = re.match(正则表达式,要匹配的字符串)
3、如果上一步匹配到数据的话,可以使用group方法来提取这个匹配到的数据
ret.group()
一句话概括,正则就是用来匹配字符串
二、匹配单个字符
. 匹配除\n之外的一个任意字符
re.match("hello.", "helloworld").group() # hellow
re.match("hello.", "hello2").group() # hello2
re.match("hello.", "hello\n").group() # 报异常
re.match("hello.", "hello").group() # 报异常
[] 匹配集合内的任意一个字符
re.match("hello[ab]", "helloa").group()
re.match("hello[ab]", "hellob").group()
re.match("hello[ab]", "helloc").group()
re.match("hello[0123456789]", "hello1").group()
re.match("hello[0123456789]", "helloq").group()
[-] 匹配范围内的任意一个字符 [a-z] [A-Z] [0-9]
re.match("hello[0-9]", "helloq").group()
re.match("hello[0-9]", "hello0").group()
re.match("hello[a-z]", "hello0").group()
re.match("hello[a-z]", "hellox").group()
re.match("hello[a-z]", "helloY").group()
re.match("[A-Z]ello", "hello").group()
[^] 禁止匹配范围内的任意一个字符 [^a-z] -取反
re.match("Hello[^0-9]", "Hello1").group() # 报异常
re.match("Hello[^0-9]", "Helloa").group() # Helloa
注意: 把^写在[]里面最前
\d 匹配一个数字 [0-9]
\D 匹配一个非数字 [^0-9]
re.match("hello\d", "hello0").group() # hello0
re.match("hello\d", "hello9").group() # hello9
re.match("hello\d", "helloa").group() # 报异常
re.match("神舟\d号升空了", "神舟1号升空了").group() # 神舟1号升空了
re.match("神舟\d号升空了", "神舟a号升空了").group() # 报异常
\s space空白字符包括换行
\S 匹配除了 空白字符
re.match("神舟\s号升空了", "神舟 号升空了").group() # 神舟 号升空了
re.match("神舟\s号升空了", "神舟\t号升空了").group() # 神舟 号升空了
re.match("神舟\s号升空了", "神舟\n号升空了").group()
\w word 等价 [a-zA-Z0-9_] \W 等价 [^a-zA-Z0-9_]
re.match("神舟\w号升空了", "神舟1号升空了").group()
re.match("神舟\w号升空了", "神舟A号升空了").group()
re.match("神舟\w号升空了", "神舟_号升空了").group()
re.match("神舟\W号升空了", "神舟_号升空了").group()
re.match("神舟\W号升空了", "神舟1号升空了").group()
re.match("神舟\W号升空了", "神舟A号升空了").group()
re.match("神舟\W号升空了", "神舟@号升空了").group()
三、匹配多个字符
\d{m} 匹配m次数字字符 = {m,m}
re.match("神舟\d\d号升空了", "神舟10号升空了").group()
re.match("神舟\d\d\d\d\d号升空了", "神舟10000号升空了").group()
re.match("神舟\d{5}号升空了", "神舟10000号升空了").group()
re.match("神舟\d{10}号升空了", "神舟1000000000号升空了").group()
{n,m} 匹配至少n次 至多m次
{n,} 匹配至少n次
re.match("神舟\d{1,10}号升空了", "神舟1号升空了").group()
re.match("神舟\d{1,10}号升空了", "神舟100000号升空了").group()
re.match("\d{3,4}-\d{6,8}","020-12345678").group()
re.match("\d{3,4}-\d{6,8}","0755-1234567").group()
+ 匹配至少1次 {1,}
re.match("神舟\d{1,}号升空了", "神舟100000号升空了").group()
re.match("神舟\d{1,}号升空了", "神舟1000000000000000000号升空了").group()
re.match("神舟\d+号升空了", "神舟1000000000000000000号升空了").group()
* 匹配至少0次 匹配任意多次 {0,}
re.match("神舟\d{0,}号升空了", "神舟号升空了").group()
re.match("神舟\d{0,}号升空了", "神舟11111号升空了").group()
re.match("神舟\d*号升空了", "神舟11111号升空了").group()
re.match("神舟\d*号升空了", "神舟号升空了").group()
? 匹配0次或者1次 {0,1}
re.match("神舟\d{0,1}号升空了", "神舟号升空了").group()
re.match("神舟\d{0,1}号升空了", "神舟1号升空了").group()
re.match("神舟\d?号升空了", "神舟1号升空了").group()
re.match("神舟\d?号升空了", "神舟号升空了").group()
案例:匹配合法的Python标识符
ret = re.match("[A-Z_a-z]\w*", "a").group()
练习:匹配出163的邮箱地址(验证是否合法),且@符号之前有4到20位,例如hello@163.com(我们规定@前面的字符串是字母,下划线、数字组成)
ret = re.match("[A-Z_a-z]\w*", "a").group()
四、匹配位置
^ 匹配开始位置
$ 匹配结束位置
re.match("\w{4,20}@163.com","123456@163.com").group()
re.match("\w{4,20}@163.com","123456@163Acom").group()
re.match("\w{4,20}@163\.com","123456@163.com").group()
re.match("\w{4,20}@163\.com","123456@163Acom").group()
re.match("\w{4,20}@163\.com","123456@163.com.cc").group()
re.match("\w{4,20}@163\.com","cc.123456@163.com.cc").group()
re.search("\w{4,20}@163\.com","cc.123456@163.com.cc").group()
re.search("^\w{4,20}@163\.com$","cc.123456@163.com.cc").group()
re.search("^\w{4,20}@163\.com$","123456@163.com.cc").group()
re.search("^\w{4,20}@163\.com$","123456@163.com").group()
re.match("^\w{4,20}@163\.com$","cc.123456@163.com").group()
五、分组
1,匿名
| 匹配左边或者右边的正则表达式
(b|a) 匹配 在分组括号内 左边或者右边的正则表达式
目的: 将目标数据从整理提取到某个位置
创建:
(正则)
获取分组结果:
.group() == .group(0) 获取到的正则表达式 整体匹配到的结果
.group(编号) 用户的分组从下标1开始
在正则中引用分组:
目的: 将前面正则匹配到的数据 用在后续某个位置 进行匹配
形式: \分组编号
例: 匹配一个座机号: 区号-座机号 注:区号3到4位数字, 座机号6到8位数字
re.match("(\d{3,4})-(\d{6,8})","020-12345678").group(1)
re.match("(\d{3,4})-(\d{6,8})","020-12345678").group(2)
re.match("(\d{3,4})-(\d{6,8})","020-12345678").group(0)
print(re.match("((\d{3,4})-(\d{6,8}))", "020-12345678").group(1)) # 020-12345678
print(re.match("((\d{3,4})-(\d{6,8}))", "020-12345678").group(2)) # 020
print(re.match("((\d{3,4})-(\d{6,8}))", "020-12345678").group(3)) # 123456789
re.match("(\d{3,4})-(\d{6,8}) \\1-\\2","020-12345678 020-12345678").group(0)
re.match("(\d{3,4})-(\d{6,8}) \\1-\\2","020-12345678 020-12345678").group(1)
re.match("(\d{3,4})-(\d{6,8}) \\1-\\2","020-12345678 020-12345678").group(2)
2-有名
优点: 分组编号发生变化会影响匿名分组
创建有名:
(?P<分组名>正则)
获取分组结果
.group(分组编号) 等价于 .group(分组名字)
在正则中引用分组:
(?P=分组名字)
re.match("((\d{3,4})-(\d{6,8}))","021-12345678 021-12345678").group()
re.match("((\d{3,4})-(\d{6,8}))","021-12345678 021-12345678").group(1)
re.match("((\d{3,4})-(\d{6,8}))","021-12345678 021-12345678").group(3)
re.match("((\d{3,4})-(\d{6,8}))","021-12345678 021-12345678").group(2)
re.match("((\d{3,4})-(\d{6,8})) \\2-\\3","021-12345678 021-12345678").group(3)
re.match("(?P<quhao>\d{3,4})-(?P<zuoji>\d{6,8}) (?P=quhao)-(?P=zuoji)","021-12345678 021-12345678)
re.match("(?P<quhao>\d{3,4})-(?P<zuoji>\d{6,8}) (?P=quhao)-(?P=zuoji)","021-12345678 021-12345678")
re.match("(?P<quhao>\d{3,4})-(?P<zuoji>\d{6,8}) (?P=quhao)-(?P=zuoji)","021-12345678 021-12345678")
re.match("(?P<quhao>\d{3,4})-(?P<zuoji>\d{6,8}) (?P=quhao)-(?P=zuoji)","021-12345678 021-12345678")
re.match("(?P<quhao>\d{3,4})-(?P<zuoji>\d{6,8}) (?P=quhao)-(?P=zuoji)","021-12345678 021-12345678")