linux 内核模块 正则表达式搜索,Python中正则表达式(re模块)的使用

1、正则表达式的概述

(1)概述:正则表达式是一些由字符和特殊符号组成的字符串,他们描述了模式的重复或者表示多个字符,正则表达式能按照某种模式匹配一系列有相似特征的字符串。正则表达式是一种小型的、高度的专业化的编程语言,

(2)Python语言中的正则表达式内嵌在Python中通过re模块实现,正则表达式被编译成一系列的字节码,然后由C编写的匹配引擎执行

2、字符匹配

(1)符号匹配

符号

描述

示例

实例说明

literal

匹配文本字符串的字面值literal

root

匹配字符串root

re1|re2

匹配正则表达式re1或者re2

root|admin

匹配字符串root或者admin

.

匹配除换行外的任意字符

a.c

匹配ac中间有任意一个字符的选项

^

匹配字符串的起始部分

^root

匹配以root开头的结果

$

匹配字符串的结束部分

*sh$

匹配以sh结尾的内容

*

匹配0次或多次前面出现的内容的正则表达式

[a-z]*

匹配0次或多次出现小写字母

+

匹配1次或多次前面出现的内容的正则表达式

[A-Z]+

匹配大写字母至少出现一次

匹配0次或1次前面出现的正则表达式

goo?

匹配go或者goo

[…]

匹配来自字符集的任一单一字符

a[0-9]c

匹配ac中间出现一个数字

[..x-y..]

匹配x到y范围中的任一单一字符

[a-zA-Z]

匹配字母

[^…]

不匹配此字符集中出现的任何一个字符,包括某一范围字符

[^A-Za-z0-9]

匹配非字母、数字

{n}

匹配n次前面出现的正则表达式

[0-9]{3}

匹配三个数字

{n,m}

匹配n到m此前面出现的正则表表达式

[0-9]{5,7}

匹配数字出现5到7次

(…)

匹配封闭的正则表达式,然后另存为子组

([0-9]{3}\.)

匹配三个数字+.存为一个组

(2)特殊字符的匹配

符号

描述

示例

\d

匹配任何十进制数字,与[0-9]一致

data\d+.txt

\D

匹配任何非数字

a\D?\.log

\w

匹配任何字母数字字符(\W与之相反)

[A-Za-z]\w+

\s

匹配任何空格字符,与[\n\t\r\v\f]相同,\S功能相反

of\sthe

\b

匹配任何单词边界(\B功能相反)

\bthe\b

\N

匹配以保存的子组N

price:\16

\A(\Z)

匹配字符串的起始(结束)

\ADear

3、Python正则表达式的使用(即re模块的使用)

函数/方法

作用

compile(pattern,flags=0)

使用任何可选的标记来编译正则表达式的模式,然后返回一个正则表达式对象

re模块函数和正则表达式对象的方法

match(pattern,string,flags=0)

尝试使用带有可选的标记的正则表达式的模式来匹配字符串,如果匹配成功就返回匹配对象;失败,返回none

search(pattern,string,flags=0)

使用可选标记搜索字符串中第一次出现正则表达式的模式,如果匹配成功则返回匹配对象,失败,返回none

findall(pattern,string[,flags])

查找字符串中所有(非重复)出现的正则表达式模式,如果匹配成功,则返回匹配对象,如果失败,返回none

finditer(patter,string[,flags])

与findall函数相同,但返回的不是一个列表,而是一个迭代器,对于每一次匹配,迭代器都返回一个匹配对象

split(pattern,string,max=0)

根据正则表达式的模式分隔符,split函数将字符串分割为列表,然后返回成功匹配的列表,分割最多操作max次(默认分割所有)

sub(pattern,repl,string,count=0)

使用repl替换所有正则表达式的模式在字符串中出现的位置,除非定义count,否则,就替换所有出现的位置

purge()

清楚隐式编译的正则表达式

group(num=0)

返回整个匹配对象,或者编号为num的特定子组

groups(default=None)

返回一个包括所有子组的元组,(如果没有匹配成功,则返回一个空元组)

groupdict(default=None)

返回一个包含所有匹配的的命名子组的字典,所有的子组名称作为字典的键(如果没有匹配,则返回空字典)

(1)compile()函数

1)re.compile(strPattern[,flag])方法概述:

这个方法是Pattern类的工厂方法,用于将字符串形式的正则表达式编译为Pattern对象。第二个参数flag是匹配模式取值可以使用按位或运算符,‘|’表示同时生效,比如re.I|re.M

2)作用:可以把经常使用的正则表达式编译成正则表达式对象,这样可以提高一定的效率。如:

import  re

text = "Jgood  is a handsome boy,he is cool,clever, and so on..."

regex =  re.compile(r'\w*oo\w*')    #将正则表达式编译成对象

print(regex.findall(text))

(2)通过match()方法匹配字符串

import  re

text = "Jgood  is a handsome boy,he is cool,clever, and so on..."

regex =  re.compile(r'\w*oo\w*')    #将正则表达式编译成对象

print(regex.findall(text))

(2)通过match()方法匹配字符串

1)作用:从起始位置(开头)开始匹配,匹配成功返回一个对象,未匹配成功返回None

2)语法:match(pattern, string, flags=0)

pattern: 正则模型

string: 要匹配的字符串

falgs  : 匹配模式

3)matchobect对象的方法

group():返回被RE匹配的的字符串

start():返回匹配开始的位置

end():返回匹配结束的位置

span():返回一个元组包含匹配(开始,结束)的位置

group():返回re整体匹配的字符串,可以一次输入多个组号,对应组号匹配的字符串

group(n,m) :返回组号为n,m所匹配的字符串,如果组号不存在,则返回组号匹配的字符串

groups():返回一个包括正则表达式中所有小组字符串的元组,从1到所含的小组号,通常      groups()不需要参数,返回一个元组,元组中元素是正 则表达式中定义的组

import re

origin = "has dfuojqwlm098"

# r = re.match("h\w+", origin)

# r = re.match("h(\w+)", origin)  #在匹配到的数据中再通过\w+去匹配

r = re.match("h(?P\w+)", origin)  #给分组名名

print(r.group())  # 获取匹配到的所有结果

print(r.groups())  # 获取模型中匹配到的分组结果

print(r.groupdict())  # 获取模型中匹配到的分组结果

(3)使用search()在一个字符串中查找匹配

1)作用:search()会用它的字符串参数,在任意位置对给定正则表达式模式搜索第一次出现的匹配情况。如果搜索到成功的匹配,就会返回一个匹配对象;否则,返回None.

2)用法:同match()

importre

m =re.match('foo','seafood')

if m isnot None:

print(m.group())    #使用match匹配不到,所以没有打印

m =re.search('foo','seafood')

if m isnot None:

print(m.group())    #使用search匹配到了foo

origin = "has dayi haha hal dfuojdayi098"

r = re.search("d(\w+).*(?P\d)$", origin)

print(r.group())  # 获取匹配到的所有结果

print(r.groups())  # 获取模型中匹配到的分组结果

print(r.groupdict())  # 获取模型中匹配到的分组中所有执行了key的组

(4)重复、特殊字符及分组匹配

正则表达式中最常见的情况包括特殊字符��使用,正则表达式模式的重复出现,以及使用圆括号对匹配模式的各部分进行分组和提取操作。

import re

#一个分组多次匹配

# patt = '\w+@(\w+\.)?\w+\.com'    #创建一个匹配规则,要求括号中的内容出现0次或一次

# print(re.match(patt, 'linuxidc@126.edu.com is mail').group())

patt = '\w+@(\w+\.)*\w+\.com'    #创建一个匹配规则,匹配括号中的内容出现0次或多次

print(re.match(patt,'linuxidc@126.edu.dayi.com is mail').group())

#多个分组分别匹配

m = re.match('(\w\w\w)-(\d\d\d)', 'abc-123')

print(m.group(1))  #打印分组以中的内容

print(m.group(2))  #打印分组2中的内容

print(m.group())  #打印分组中的所有内容

#分组嵌套匹配

n = re.match('(a(b))', 'abcdefgh')

print(n.group(1))  #打印匹配到的分组1,即'(a(b))'

print(n.group(2))  #打印匹配到的分组2即'(b)'

print(n.groups())  #打印匹配到的所有分组,即'(ab)','(b)'

(5)匹配字符串的起始结尾及单词边界

import re

#开头匹配

print(re.search('^linuxidc', 'dayi123 is nb').group())

# print(re.search('^dayi', 'her is dayi').group())

#边界匹配

print(re.search(r'\bhello', 'hello world').group())#print(re.search(r'\Bhello','worldhellower').group()) #有边界匹配时会报错

print(re.search(r'\Bhello', 'worldhellower').group())

(6)使用findall和finditer()查找每一次出现的位置

findall()查询字符串中某个正则表达式模式全部的非重复出现的情况,findall返回的是一个列表,如果没有匹配到则返回一个空列表,如果匹配成功,列表包含所有成功的匹配部分(从左向有按顺序排列)

import re

origin = "has haha hal dfuojqwlm098"

print(re.findall("h\w+", origin))  #找到字符串中所有的匹配到的内容

print(re.findall("h(\w+)", origin))  #打印匹配到的列表

r = re.findall("h(\w+)a(bc)c", origin) #因为匹配不到所有打印一个空列表

print(r)

finditer()函数与findall函数类似,但finditer()返回的是一个可迭代的对象。

import re

s = 'This and that'

print(re.findall(r'(Th\w+) and (th\w+)', s, re.I))

print(re.finditer(r'(Th\w+) and (th\w+)', s, re.I).__next__().groups()) #调用返回值

print(re.finditer(r'(Th\w+) and (th\w+)', s, re.I).__next__().group(1))

it = re.finditer(r'(Th\w+)', s, re.I)  #生成一个生成器对象

g = it.__next__()  #调用

print(g.groups())  #打印出This,以元组的形式

print(g.group(1))

g = it.__next__()  #再次调用

print(g.groups())  #打印出that

#将匹配到的内容生产一个列表,列表中包含两个元组

print([g.groups(1) for g in re.finditer(r'(Th\w+)', s, re.I)])

(7)使用sub()和subn()搜索替换

sub()只替换搜索到的内容,subn()不但替换搜索到的内容,并返回替换的次数。

import re

print(re.sub("g.t","have",'I get A, I got B,I gut C'))  #对匹配到的单词替换

print(re.subn("g.t","have",'I get A, I got B,I gut C')) #对匹配到的单词替换,并返回替换次数

print(re.sub('[bd]','Y','abcdef'))

print(re.subn('[bd]','Y','abcdef'))    #对字符串替换,并打印替换的字符串的的次数

分组和替换的综合应用(替换日期的表示方法):

import re

import time,datetime

day1 = str(datetime.date.today())

print(day1)

#将月/日/年的时间格式转化成“日/月/年”,将r加在左引号之前,主要目的是为了避免转义特殊字符串字符

print(re.sub(r'(\d{1,2})/(\d{1,2})/(\d{2}|\d{4})', r'\2/\1/\3', '05/06/2017'))

print(re.sub(r"(\d{2}|\d{4})-(\d{1,2})-(\d{1,2})", r"\3/\2/\1", day1))

(8)使用split分割字符串

import re

print(re.split('\d+','one1two2three3,for4')) #以匹配到的数字对字符串以“,”进行分割

4、正则表达式的应用

(1)对Linux系统who命令输出内容进行处理

将Linux系统who命令输出结果保存到whodata.txt中:

[root@linuxidc ~]# cat whodata.txt

liu2    :0          2017-04-17 22:10 (:0)

liu2    pts/0        2017-04-17 22:11 (:0)

root    pts/1        2017-05-05 03:51(172.16.252.112)

root    pts/2        2017-05-05 03:51(172.16.252.112)

root    pts/3        2017-05-05 03:52 (172.16.252.112)

对who命令输出的内容进行处理:

import re

f = open('whodata.txt','r')

for line in f:

#对匹配到的行的内容以逗号分隔,将每一行的内容分别存到一个列表中

print(re.split(r'\s\s+',line.rstrip()))

f.close()

使用findall()函数处理win下tasklist命令:

import os

import re

f = os.popen('tasklist /nh', 'r')

for line in f:

print(re.findall(r'([\w.]+(?:[\w]+)*)\s\s+(\d+) \w+\s\s+\d+\s\s+([\d,]+ K)', line.rstrip()))

#读取每一行中自己需要的数据

f.close()

(2)生成用于正则表达式练习的数据

#!/usr/bin/env python

from random import randrange,choice

from stringimport ascii_letters as lc

from sys import maxsize

from time import ctime

tlds = ('com','deu','net','org','gov')

for i in range(randrange(5,11)):

dtint = randrange(maxsize)        #生成一个随机数字组

#在属组中取一个6到十位的随机数作为时间戳生成一个日期

dtstr = ctime(int(str(dtint)[0:randrange(6,10)]))

llen = randrange(4,8)  #生成一个4-8的随机数字

login = ''.join(choice(lc) for j in range(llen)) #生成邮箱@符号前的字符

dlen = randrange(llen,13)

dom = ''.join(choice(lc) for j in range(dlen))  #生成@后的字符,长度有dlen来决定

#choice(tlds)为在tlds总随机选择一个域名后缀

print('%s::%s@%s.%s::%d-%d-%d' % (dtstr,login,dom,choice(tlds),dtint,llen,dlen))

将上面生成的数据保存到一个文件中用于后面练习:

#!/usr/bin/env python

import re

with open('gendata.txt','r') as f:

for line in f:

patt = '.+(\d+-\d+-\d+)' #为贪婪匹配,匹配前面为任意字符,后面组中为如“5-7-10”的数据

print(re.match(patt, line).group(1))

'''"?"要求正则表达式引擎匹配尽可能少的字符,在"+","*","?"后使用可达到预期效果'''

patt1= '.+?(\d+-\d+-\d+)' #通过"?",匹配到了符合分组中的所有字符串

print(re.match(patt1, line).group(1))

0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值