python 正则表达式(Regular Expression)
-
正则表达式基础
- search():只返回第一个匹配的字符串
- findall():将搜寻结果以列表方式返回
import re # 导入re正则表达式模块 msg = "十步13466663478杀一人,千里不留15688889999" def parseString(content): """解析字符串中是否含有手机号""" # 使用re.compile()建立Regex对象 # # 手机号(共11位)第一位是1 第二位是3~9中选1位 \d表示数字 {}里面的数字代表精确匹配多少位数,{9)表示9个数字 phoneRule = re.compile(r'1[3-9]\d{9}') # 搜寻对象,search()只传回第一个匹配的字符串 phoneNum = phoneRule.search(msg) if phoneNum is not None: print(phoneNum.group()) else: print('该字符串中不包含手机号!') def parseString2(content): """解析字符串中是否含有手机号""" # 使用re.compile()建立Regex对象 # # 手机号(共11位)第一位是1 第二位是3~9中选1位 \d表示数字 {}里面的数字代表精确匹配多少位数,{9)表示9个数字 phoneRule = re.compile(r'1[3-9]\d{9}') # findall():返回匹配结果列表 phoneNum_list = phoneRule.findall(msg) if phoneNum_list: print(phoneNum_list) else: print('该字符串中不包含手机号!') def parseString3(content): """解析字符串中是否含有手机号""" # 省略re.compile() # re.findall(pattern, string, flags) # 手机号(共11位)第一位是1 第二位是3~9中选1位 \d表示数字 {}里面的数字代表精确匹配多少位数,{9)表示9个数字 pattern = r'1[3-9]\d{9}' # findall():返回匹配结果列表 phoneNum_list = re.findall(pattern=pattern, string=msg) # 用列表传回搜寻结果 if phoneNum_list: print(phoneNum_list) else: print('该字符串中不包含手机号!') parseString(msg) # 13466663478 parseString2(msg) # ['13466663478', '15688889999'] parseString3(msg) # ['13466663478', '15688889999']
-
使用小括号分组
# author:mlnt # createdate:2022/8/15 import re # 导入re正则表达式模块 msg = "十步134-6666-3478杀一人,千里不留156-8888-9999" """ 我国使用的手机号码为11位数字,我们的手机号可以分为三段,都有不同的编码含义: 前3位是网络识别号、4-7位是地区编码(HLR归属位置寄存器)、8-11位是用户号码(随机分配) """ def parseString(content): """解析字符串中是否含有手机号""" # re.findall(pattern, string, flags) # 手机号(共11位)第一位是1 第二位是3~9中选1位 \d表示数字 {}里面的数字代表精确匹配多少位数 pattern = r'(1[3-9]\d)-(\d{4})-(\d{4})' # findall():返回匹配结果列表 phoneNum_list = re.findall(pattern=pattern, string=msg) # 用元组列表传回搜寻结果 if phoneNum_list: print(phoneNum_list) else: print('该字符串中不包含手机号!') def parseString2(content): """解析字符串中是否含有手机号""" # 使用re.compile()建立Regex对象 # 手机号(共11位)第一位是1 第二位是3~9中选1位 \d表示数字 {}里面的数字代表精确匹配多少位数 pattern = r'(1[3-9]\d)-(\d{4})-(\d{4})' # 搜寻对象,search()只传回第一个匹配的字符串 phoneNum = re.search(pattern=pattern, string=msg) if phoneNum is not None: # 前3位是网络识别号、4-7位是地区编码(HLR归属位置寄存器)、8-11位是用户号码(随机分配) print(phoneNum.group()) network_num, area_num, user_num = phoneNum.groups() print(f'网络识别号:{network_num}') print(f'地区编码:{area_num}') print(f'用户号码:{user_num}') else: print('该字符串中不包含手机号!') parseString(msg) # [('134', '6666', '3478'), ('156', '8888', '9999')] parseString2(msg) # 134-6666-3478 # 网络识别号:134 # 地区编码:6666 # 用户号码:3478
-
使用管道|
| --> pipe 管道,使用管道可以同时搜寻比对多个字符串
# | --> pipe 管道,使用管道可以同时搜寻比对多个字符串 import re msg = 'Jack and Maria are good friends. They always go to school together.' pattern = 'Tom|Jack' # 搜寻Tom和Jack result = re.findall(pattern=pattern, string=msg) print(result) # ['Jack'] pattern = 'Mary|John|Jackson|Maria|Jack' result = re.findall(pattern=pattern, string=msg) print(result) # ['Jack', 'Maria']
-
多个分组的管道搜索
# author:mlnt # createdate:2022/8/15 import re msg = 'Jackson, Jacknason, Jacknion and Maria are good friends. They always go to gym together.' pattern = 'Jack(son|nason|nion|nice)' result = re.findall(pattern=pattern, string=msg) print(result) # ['son', 'nason', 'nion']
-
使用问号(?)做搜索
正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。
正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。
特殊字符:- $:匹配输入字符串的结尾位置
- ():标记一个子表达式的开始和结束位置
- *:匹配前面的子表达式0次或多次
- +:匹配前面的子表达式1次或多次
- .:匹配除换行符(\n)之外的任意单个字符
- [:标记一个中括号表达式的开始
- ?:匹配前面的子表达式0次或1次,或指明一个非贪婪限定符
- \:将下一个字符标记为特殊字符、原义字符、向后引用或八进制转义符
- ^:匹配输入字符串的开始位置。当该符号在方括号表达式中使用时,表示不接受该方括号中的字符集合
- {:标记限定符表达式的开始
- |:指明两项之间的一个选择
# author:mlnt # createdate:2022/8/15 """ 正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。 正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。 特殊字符: - $:匹配输入字符串的结尾位置 - ():标记一个子表达式的开始和结束位置 - *:匹配前面的子表达式0次或多次 - +:匹配前面的子表达式1次或多次 - .:匹配除换行符(\n)之外的任意单个字符 - [:标记一个中括号表达式的开始 - ?:匹配前面的子表达式0次或1次,或指明一个非贪婪限定符 - \:将下一个字符标记为特殊字符、原义字符、向后引用或八进制转义符 - ^:匹配输入字符串的开始位置。当该符号在方括号表达式中使用时,表示不接受该方括号中的字符集合 - {:标记限定符表达式的开始 - |:指明两项之间的一个选择 """ """ 在正则表达式中,若某些括号内的字符串或正则表达式可有可无,可以在后面加上? """ import re msg = 'Jackson and Maria are good friends. They always go to gym together.' pattern = 'Jack((na)?son)' result = re.search(pattern=pattern, string=msg) print(result.group()) # Jackson
-
使用星号(*)做搜索
在正则表达式中,若某些字符串或正则表达式可出现0次到多次,可在后面加*
# author:mlnt # createdate:2022/8/15 """ 在正则表达式中,若某些字符串或正则表达式可出现0次到多次,可在后面加* """ import re msg = 'Jackson, Jacknason, Jacknion, Jackkkkjjan, Jackken and Maria are good friends. They always go to gym together.' pattern = 'Jack((k)*)' result = re.search(pattern=pattern, string=msg) print(result.group()) # Jack
-
使用加号(+)做搜索
在正则表达式中,若某些字符或正则表达式可出现1次或多次,可在后面加+
# author:mlnt # createdate:2022/8/15 """ 在正则表达式中,若某些字符或正则表达式可出现1次或多次,可在后面加+ """ import re msg = 'Jackson, Jackckson, and Maria are good friends. They always go to gym together.' pattern = 'Jack((ck)+son)' result = re.search(pattern=pattern, string=msg) print(result.group()) # Jackckson
-
搜索时忽略大小写
搜寻时,若是在search()或findall()内增加迪桑参数re.I或re.IGNORECASE,搜寻时会忽略大小写
# author:mlnt # createdate:2022/8/15 """ 搜寻时,若是在search()或findall()内增加迪桑参数re.I或re.IGNORECASE,搜寻时会忽略大小写 """ import re msg = 'JACK and Maria are good friends. They always go to school together.' pattern = 'Tom|Jack' # 搜寻Tom和Jack result = re.findall(pattern=pattern, string=msg, flags=re.IGNORECASE) print(result) # ['JACK'] pattern = 'Mary|John|Jackson|Maria|Jack' result = re.findall(pattern=pattern, string=msg, flags=re.I) print(result) # ['JACK', 'Maria']
-
正则表达式的特殊字符
# author:mlnt # createdate:2022/8/15 """ 特殊字符: \d: 0~9的整数数字 \D:除了0~9以外的其他字符 \s:空白、定位、Tab键、换行、换页字符 \S:除空白、定位、Tab键、换行、换页字符以外的其他字符 \w:数字、字母和下划线,[A-Za-z0-9_] \W:除数字、字母和下划线和[A-Za-z0-9_]以外的其他字符 """ import re msg = 'JACK, Jackson and Maria are good friends.' pattern = '\w+' # 不限长度的数字、字母和下划线字符 result = re.findall(pattern=pattern, string=msg, flags=re.IGNORECASE) print(result) # ['JACK', 'Jackson', 'and', 'Maria', 'are', 'good', 'friends'] pattern = 'Jack\w*' # Jack开头,后接0或多个数字、字母和下划线 result = re.findall(pattern=pattern, string=msg, flags=re.I) print(result) # ['JACK', 'Jackson'] msg2 = '2 tigers, 3 dogs, 5 pigs' pattern = '\d+\s\w+' result = re.findall(pattern=pattern, string=msg2, flags=re.I) print(result) # ['2 tigers', '3 dogs', '5 pigs'] """ 字符分类: [a-z]:代表a-z的小写字符 [A-Z]:代表A-Z的大写字符 [aeiouAEIOU]:代表英文发音的元音字符 [2-5]:代表2-5的数字 在字符分类中,中括号内可以不加上”\“进行”.“、”?“、”*“、"(”、“)”等字符的转义 """ msg = 'JACK, Jackson and Maria are good friends.' pattern = '[aeiouAEIOU]' result = re.findall(pattern=pattern, string=msg, flags=re.IGNORECASE) print(result) # ['A', 'a', 'o', 'a', 'a', 'i', 'a', 'a', 'e', 'o', 'o', 'i', 'e'] msg2 = '2 tigers, 3 dogs, 5. pigs' pattern = '[2-5.]' result = re.findall(pattern=pattern, string=msg2, flags=re.I) print(result) # ['2', '3', '5', '.'] # 字符分类的^字符 # 如果在中括号内加上^,表示搜寻除这些字符以外的所有字符 msg = 'Jackson and Maria are good friends.' pattern = '[^aeiouAEIOU]' result = re.findall(pattern=pattern, string=msg, flags=re.IGNORECASE) print(result) # ['J', 'c', 'k', 's', 'n', ' ', 'n', 'd', ' ', 'M', 'r', ' ', 'r', ' ', 'g', 'd', ' ', 'f', 'r', 'n', 'd', 's', '.'] msg2 = '2 tigers, 3 dogs, 5. pigs' pattern = '[^2-5.]' result = re.findall(pattern=pattern, string=msg2, flags=re.I) print(result) # [' ', 't', 'i', 'g', 'e', 'r', 's', ',', ' ', ' ', 'd', 'o', 'g', 's', ',', ' ', ' ', 'p', 'i', 'g', 's'] # 正则表达式法的^字符 # 在正则表达式起始位置加上^字符,表示正则表达式法的字符串必须出现在被搜寻字符串的起始位置 msg = 'Jack and Maria are good friends.' msg2 = 'Mary and Jack are good friends.' pattern = '^Jack' result1 = re.findall(pattern=pattern, string=msg) result2 = re.findall(pattern=pattern, string=msg2) print(result1) # ['Jack'] print(result2) # [] # 正则表达式法的$字符 # 正则表达式法的末端放置$字符时,表示正则表达式的字符串必须出现在被搜寻字符串的末尾 msg = 'Generally speaking, both males and females are of age at 18.' pattern1 = '\W$' # 以除英文字母、数字、下划线之外的其他字符结尾 pattern2 = '\d$' # 以数字结尾 result1 = re.findall(pattern=pattern1, string=msg) result2 = re.findall(pattern=pattern2, string=msg2) print(result1) # ['.'] print(result2) # [] # 单一字符使用通配符“.” # 通配符“.”匹配除换行符以外的所有单个字符 msg = 'Generally speaking, both males and females are of age at 18.' pattern = '.re' result = re.findall(pattern, msg) print(result) # ['are'] # 所有字符使用通配符“.*” # .*:可以匹配所有字符,表示匹配0到多个通配符(换行符除外) msg = 'Name: Jack, Age: 18 Tel: 13838384438' pattern = 'Name: (.*) Age: (.*) Tel: (.*)' result = re.search(pattern=pattern, string=msg) name, age, tel = result.groups() print(f'Name: {name}, Age: {age}, Tel: {tel}') # Name: Jack,, Age: 18, Tel: 13838384438 # 换行字符的处理 # 用“.*”搜寻时,遇到换行字符“\n”则停止 # re模块提供参数re.DOTALL,功能包括搜寻换行字符 msg = 'Name: Jack, Age: 18 \nTel: 13838384438' pattern = '(.*)' result1 = re.search(pattern=pattern, string=msg) print(result1.group()) # Name: Jack, Age: 18 result2 = re.search(pattern=pattern, string=msg, flags=re.DOTALL) print(result2.group()) # Name: Jack, Age: 18 # Tel: 13838384438
-
re.match()MatchObject对象内容的重要方法
- re.match()只搜寻比对字符串开头,成功返回MatchObject对象,失败则返回None
- group():返回搜寻到的字符串
- end():返回搜寻到的字符串的结尾位置
- start():返回搜寻到的字符串的起始位置
- span():返回字符串的(起始,结束)位置
# author:mlnt # createdate:2022/8/15 """ re.match()只搜寻比对字符串开头,成功返回MatchObject对象,失败则返回None re.search()搜寻整个字符串,成功返回MatchObject对象,失败则返回None """ """ MatchObject对象内容的重要方法: - group():返回搜寻到的字符串 - end():返回搜寻到的字符串的结尾位置 - start():返回搜寻到的字符串的起始位置 - span():返回字符串的(起始,结束)位置 """ import re msg = 'Jack and Maria are good friends.' msg2 = 'Mary and Jack are good friends.' pattern = 'Jack' result1 = re.match(pattern=pattern, string=msg) if result1 is not None: print(result1.group()) # Jack print(result1.start()) # 0 print(result1.end()) # 4 print(result1.span()) # (0, 4) result2 = re.match(pattern=pattern, string=msg2) if result2 is not None: print(result2.group())
-
sub()方法
result = re.sub(pattern, newstr, msg)
pattern是欲搜寻的字符串,如果搜寻成功,则用newstr替换,同时将结果传给result;如果搜寻到多个相同字符串,这些字符串都会被替换,原msg的内容不会改变;如果搜寻失败,则将msg内容赋值给result
# author:mlnt # createdate:2022/8/15 """ sub()方法的语法: result = re.sub(pattern, newstr, msg) pattern是欲搜寻的字符串,如果搜寻成功,则用newstr替换,同时将结果传给result; 如果搜寻到多个相同字符串,这些字符串都会被替换,原msg的内容不会改变; 如果搜寻失败,则将msg内容赋值给result """ import re msg = "十步13466663478杀一人,千里不留15688889999" pattern = r'(1[3-9]\d+)(\d{4})(\d{4})' newstr = r'\1****\3' # 第2个分组用*替换 result = re.sub(pattern=pattern, repl=newstr, string=msg) print(result) # 十步134****3478杀一人,千里不留156****9999
-
电子邮箱地址的搜寻
# author:mlnt # createdate:2022/8/15 import re # 在正则表达式中加注释,需使用re.VERBOSE参数 def get_mail(content): """提取邮箱""" pattern = r"""( [a-zA-Z0-9_-]+ # 用户账号 @ # @符号 [a-zA-Z0-9]+ # 主机域名domain [\.] # .符号 [a-zA-Z]{2,4} # com/edu或其他 ([\.])? # .符号 ([a-zA-Z]{2,4})? # 国别 )""" results = re.findall(pattern, content, re.VERBOSE) return results content = 'test@163.com 998@gmail.com' print(get_mail(content)) # [('test@163.com', '', ''), ('998@gmail.com', '', '')]