首页 > 技术文章 > 正则表达式

qingchang 2018-05-19 15:33 原文

正则表达式: 正则表达式就是记录文本规则的代码
    这些具有规则的字符被称为元字符
 
“匹配单个字符”
 
字符
功能
.
匹配任意1个字符(除了\n)
[ ]
匹配[ ]中列举的字符
\d
匹配数字,即0-9
\D
匹配非数字,即不是数字
\s
匹配空白,即 空格,tab键
\S
匹配非空白
\w
匹配单词字符,即a-z、A-Z、0-9、_
\W
匹配非单词字符
{注1:仅占单个字符位置}
{注2:[0-9a-z]:表示匹配0-9/a-z任意一个数字/字母都行}
{注3::[^47]:表示除了4或者7以外的数据都可以匹配}
{注4:. 必须占一个字符位置,并不是可无}
 
 
“匹配多个字符的相关格式”
 
字符
功能
* 匹配前一个字符出现0次或者无限次,即可有可无
+ 匹配前一个字符出现1次或者无限次,即至少有1次
? 匹配前一个字符出现1次或者0次,即要么有1次,要么没有
{m} 匹配前一个字符出现m次
{m,n} 匹配前一个字符出现从m到n次
{注1:"?":也可以用于贪婪模式下仅查找第一个,不再索取后面相匹配的数据}
{注2:"限定符+?":多取少,尽可能少重复}
{注3:一般配合单个字符搭配使用,用在字符后面。}
 

“匹配开头结尾”

字符
功能
^
匹配字符串开头
$
匹配字符串结尾
{注1:锁死查找数据的开头和结尾,用于数据查找固定的长度框架}
 
 

“匹配分组”

字符
功能
|
匹配左右任意一个表达式
(ab)
将括号中字符作为一个分组
\num
引用分组num匹配到的字符串
(?P<name>)
分组起别名
(?P=name)
引用别名为name分组匹配到的字符串
 
Python中字符串前面加上 r 表示原生字符串
与大多数编程语言相同,正则表达式里使用"\"作为转义字符
r:表示原始字符串,不需要对反斜杠进行转义,也就是这个里面的反斜杠是一个真正意义上的反斜杠
r的作用:就是不需要给反斜杠进行转义了,不对其它字符进行操作
如下:
match_obj = re.match(r"c:\\a\\b\\c", my_str)
if match_obj:
print(match_obj.group())
else:
print("匹配失败")

 

 
  

python贪婪和非贪婪

Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪则相反,总是尝试匹配尽可能少的字符。
在"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪。
解决方式:非贪婪操作符“?”,这个操作符可以用在"*","+","?"的后面,要求正则匹配的越少越好。
代码/语法
说明
*?
重复任意次,但尽可能少重复
+?
重复1次或更多次,但尽可能少重复
??
重复0次或1次,但尽可能少重复
{n,m}?
重复n到m次,但尽可能少重复
{n,}?
重复n次以上,但尽可能少重复
 
 
 
导入模块 :import re
方法:re.match("参数1","参数2")        
        match:根据比正则表达式从头开始匹配数据
          参数1:正则表达式的代码
          参数2:要匹配的字符串
           match_obj.group():返回匹配的结果
match_obj = re.match("t.o", "two123456")
if match_obj:
    # 获取匹配的结果
    print(match_obj.group())
else:
    print("匹配失败")
注:match只从头开始匹配,末尾另有数据(123456)也会匹配成功,只输出相对应的结果,其后面的数据不显示。
 
# 扩展- 匹配qq
match_obj = re.match("(qq):(1\d{4,11})", "qq:10987")
if match_obj:
print(match_obj.group())
# 表示获取第一个分组的数据
print(match_obj.group(1))
# 表示获取第二个分组的数据
print(match_obj.group(2))
else:
print("匹配失败")
注:.group(1),group(2):获取相对应的分组数据,从左往右,分组以()定义
 
\num可以引用其分组。如下:
# 扩展- 匹配qq
match_obj = re.match("(qq):(1\d{4,11})", "qq:10987")
if match_obj:
print(match_obj.group())
# 表示获取第一个分组的数据
print(match_obj.group(1))
# 表示获取第二个分组的数据
print(match_obj.group(2))
else:
print("匹配失败")

 

(?P<name>)    分组起别名
(?P=name)    引用别名为name分组匹配到的字符串 
如下:
match_obj = re.match("<(?P<name1>[a-zA-z0-9]+)><(?P<name2>[a-zA-z0-9]+)>.*</(?P=name2)></(?P=name1)>", "<html><h1>www.itcast.cn</h1></html>")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")
 
 
方法:re.search(参数1,参数2)
        search:根据正则表达式查找数据
        参数1:正则表达式
        参数2:要匹配的字符串
match_obj = re.search("\d+", "水果有20个30")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")
 
 
方法:re.findall(参数1,参数2)
        findall:根据正则表达式查找多个数据,数据以列表的方式返回
        参数1:正则表达式
        参数2:要匹配的字符串
result = re.findall("\d+", "苹果20个鸭梨10个总共30个水果")
print(result)

 

 
方法:re.sub(参数1,参数2,参数3,count=1)
        sub:根据正则表达式替换数据
        参数1:正则表达式
        参数2:替换的任务
        参数3:要匹配的字符串
        count:替换的次数,默认全部替换,可以指定换次数
result = re.sub("\d+", "200", "阅读数:10 评论数:10", count=1)
print(result)
 
 
方法:re.split(参数1,参数2,maxsplit=1)
        split:根据正则表达式进行分割数据
        参数1:正则表达式
        参数2:要匹配的字符串
        maxsplit:表示最大分割次数(默认全部分割)
result = re.split(":|,", "哈哈:呵呵,嘻嘻:嘿嘿", maxsplit=1)
print(result)

 

 
 

推荐阅读