python之正则表达式方法详解

正则表达式是NLP中的基本应用。正则表达式是一种定义了搜索模式的特征序列,主要用于字符串的模式匹配,或是字符的匹配。re模块是操作正则表达式的模块。

一,re.match匹配

1,re.match的用法

re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

a)函数语法
re.match(pattern, string, flags=0)
# re.match(<正则表达式>,<需要匹配的字符串>)
b)函数参数说明
参数 描述
pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志
c)返回匹配对象

匹配成功re.match方法返回一个匹配的对象,否则返回None。
我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。

匹配对象方法 描述
group(num=0) 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
groups() 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。
2,re.match的实例
a)实例1
import re
print(re.match('www', 'www.runoob.com'))  # 在起始位置匹配
print(re.match('www', 'www.runoob.com').group())  # 返回匹配到的内容
print(re.match('www', 'www.runoob.com').span())  # 返回匹配到的内容在文本的索引
print(re.match('com', 'www.runoob.com')) 

# ---output-----
<_sre.SRE_Match object; span=(0, 3), match='www'>
www
(0, 3)
None

注意:

  • 返回的match对象使用span()方法将返回匹配索引。
  • 如若没有匹配到结果,将返回None
b)实例2
import re

line = "Cats are smarter than dogs"
matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)

if matchObj:
   print ("matchObj.group() : ", matchObj.group())
   print ("matchObj.group(1) : ", matchObj.group(1))
   print ("matchObj.group(2) : ", matchObj.group(2))
   print ("matchObj.groups() : ", matchObj.groups())
else:
   print ("No match!!")
   
# ---output------------
matchObj.group() :  Cats are smarter than dogs
matchObj.group(1) :  Cats
matchObj.group(2) :  smarter
matchObj.groups() :  ('Cats', 'smarter')
二,正则表达式模式
1,匹配单个字符
匹配符号 匹配含义
. 匹配任意1个字符(除了\n,可以使用re.S包含\n)
[ ] 匹配[]中列举的字符
\d 匹配数字,即0-9
\D 匹配非数字,即不是数字
\s 匹配空白,即空格,tab键
\S 匹配非空白
\w 匹配非空白,即a-z,A-Z,0-9,_,汉字
\W 匹配特殊字符,即非字母,非数字,非汉字

注意:

  • ’ . '可以匹配除了 \n 的唯一字符,若想要匹配\n,可在正则表达式后加上re.S .
  • \w 还可以匹配多种语言,所以需要慎用。
  • \s 可以匹配到 \n
  • [ ]中匹配10个数字可用[0-9],26个字母可用[a-z]
  • [ ]中匹配除了指定字符以外都匹配:[^abcde]
2,匹配多个字符
匹配符号 匹配含义
* 匹配前一个字符出现0次或者无限次,即可有可无
+ 匹配前一个字符出现1次或者无限次,即至少有1次
? 匹配前一个字符出现1次或者0次,即要么有1次,要么没有
{m} 匹配前一个字符出现m次
{m,n} 匹配前一个字符出现从m到n次

注意:
此处可以体现出正则表达式的贪婪特性,在同等条件下,会自动使*、+、?、{1,5}匹配多的字符,取消贪婪特性可使用*?、 +?、 ??、 {}?

3,匹配开头和结尾、除了指定字符都匹配
a)匹配开头和结尾

在表达式中若有^代表匹配内容的首字符应该与正则表达式中的首字符匹配,否则无输出。
在表达式中若有$代表匹配内容的末字符应该与正则表达式中的末字符匹配,否则无输出。

匹配符号 匹配含义
^ 匹配字符串开头
$ 匹配字符串结尾
b)除了指定字符都匹配
[^指定字符]: 表示除了指定字符都匹配
# [^>]*> 表示 只要不是 字符> 就可以匹配多个,直到遇到>
# | 在此处表示 并
re.sub(r'<[^>]*>|\s|&nbsp;','',strs)       # 表示将strs中在匹配到的字符替换成无,并输出替换后的strs
4,匹配分组
  • 字符‘|’ 在此处表示 或 ,由括号()来限定或的范围
  • ()中的字符作为分组,group(num)中的num指定取出哪个分组
  • \num 在正则表达式中引用分组num匹配到的字符
  • (?P)分组起别名 (?P=name)引用别名为name分组匹配到的字符串
匹配符号 匹配含义
| 匹配左右任意一个表达式
(ab) 将括号中字符作为一个分组
\num 引用分组num匹配到的字符串
(?P) 分组其别名
(?P=name) 引用别名为name分组匹配到的字符串
三,re.search匹配

与match的区别为:不从开头开始匹配,在文中寻找匹配项,只查找一次

import re

# 根据正则表达式查找数据,注意:只查找一次
match_obj = re.search("\d+","水果有20个,其中苹果10个.")
if match_obj:
    # 获取匹配结果数据
    print(match_obj.group())
else: 
    print("匹配失败")

#---output-----
20
四,re.findall匹配

与search基本相同,但可以查找多次

import re

# 根据正则表达式查找数据,注意:只查找一次
result = re.findall("\d+","水果有20个,其中苹果10个.")
print(result)

# ---output------
['20', '10']
五,re.sub 将匹配到的数据进行替换
1,使用字符串进行替换
import re 

# count=0 替换次数,默认全部替换,count=1根据指定次数替换
result = re.sub("\d+","2","评论数:10,点赞数:20",count=1)
print(result)

# ---output------
评论数:2,点赞数:20
2,使用函数进行替换
import re 

# match_obj:该参数系统自动传入
def add(match_obj):
    # 获取匹配结果的数据
    value = match_obj.group()
    result = int(value) + 1 
    # 返回值必须是字符串类型
    return str(result)

result = re.sub("\d+",add,"阅读数:10")
print(result)

# ---output-----
阅读数:11
六,re.split(| 表示 并)

根据匹配进行切割字符串,并返回一个列表

import re 

ret = re.split(r":| ",'info:xiaozhang 33 shangdong')
print(ret)

# ---output----
['info', 'xiaozhang', '33', 'shangdong']
七,贪婪与非贪婪

在"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪。

import re 

s = "This is a number 234-235-22-423"
r = re.match(".+(\d+-\d+-\d+-\d+)",s)
print(r.group(1))

#---output------
4-235-22-423

正则表达式模式中使用到通配字,那它在从左到右的顺序求值时,会尽量“抓取”满足匹配最长字符串,在我们上面的例子里面,“.+”会从字符串的启始处抓取满足模式的最长字符,其中包括我们想得到的第一个整型字段的中的大部分,“\d+”只需一位字符就可以匹配,所以它匹配了数字“4”,而“.+”则匹配了从字符串起始到这个第一位数字4之前的所有字符。

import re 

s = "This is a number 234-235-22-423"
r = re.match(".+?(\d+-\d+-\d+-\d+)",s)
print(r.group(1))

#---output------
234-235-22-423

解决方式:非贪婪操作符“?”,这个操作符可以用在"*","+","?"的后面,这样“?”前面的正则表达式不能匹配“?”后面正则表达式的数据

八,r的作用
  • Python中字符串前面加上 r 表示原生字符串,数据里面的反斜杠不需要进行转义,针对的只是反斜杠。
  • Python里的原生字符串很好地解决了这个问题,有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。
  • 建议: 如果使用使用正则表达式匹配数据可以都加上r,要注意r针对的只是反斜杠起作用,不需要对其进行转义
match_obj = re.search('e\\\\/','''i have one nee\/dle''') 
match_obj.group()

#---output----
'e\\/'
import re 

match_obj = re.match(r"<([a-zA-Z1-9]+)>.*</\1>", "<html>hh</html>")
if match_obj:
    print(match_obj.group())
    print(match_obj.group(1))
    print(match_obj.groups())
else:
    print("匹配失败")

# ---output------
<html>hh</html>
html
('html',)

猜你喜欢

转载自blog.csdn.net/TFATS/article/details/111317995