Python中的正则表达式(Regex匹配,贪婪匹配Greedy Matching)

Python中的正则表达式(Regex匹配,贪婪匹配Greedy Matching)

什么是正则表达式?
•正则表达式(regex)是描述一组字符串的模式
匹配过程测试给定字符串是否与模式匹配,也可以修改字符串.例如,通过替换子串或将其拆分为子串
•正则表达式是一种功能强大的编程工具,广泛用于计算/文本处理(例如)在Perl、Tcl/Tk、Java、grep、sed、awk、vi、emacs、lex中找到
但请注意,regex语法各不相同
•许多应用-一些随机示例:从一组网页中删除html;从程序中提取注释块(例如构建文档);检查文档中的双字(“the”、“here here”)

简单模式
•正则表达式的最简单示例是文字模式,大多数字符只是与自己匹配.同样,大多数字符序列形成正则表达式以匹配相同的字符串中的字符序列
•但有些字符有特殊的行为:元字符(metachars)
•Python提供了广泛的正则表达式功能
⋄ 非基本语言-必须导入模块“re”
⋄ 可以使用模块函数“直接”进行正则表达式匹配

import sys, re
with open(sys.argv[1],’r’) as infs:
	for line in infs:
		if re.search(’pen’,line):
			print(line,end=’’)

搜索扫描字符串中任何位置匹配正则表达式的第一个子字符串
如果找到匹配,则返回匹配对象,否则返回无(=False)
当正则表达式要多次使用时,最好(即更快)编译正则表达式对象:

import sys, re
penRE = re.compile(’pen’)
with open(sys.argv[1],’r’) as infs:
	for line in infs:
		if penRE.search(line):
		print(line,end=’’)

将对象指定给一个命名良好的变量可以提供更可读的代码
例如具有“单词”、“URL”等的正则表达式

为了指定在匹配中允许几个选项之一,用竖条(或“管道”)将它们分开regex “car|bike|train”;可以使用括号对图案的部分进行分组regex “(e|i)nquir(e|y|ing)”

量词
•量词允许您指定您想要的数量(子)阵列的引用
•以下量词基于Kleene符号:
#* 表示零或更多; +表示1或更多;?表示零次或一次出现(即可选)
•可以用符号指定可能的重复次数:
{3,12}指至少3次,最多12次;{,12}指零到12次之间;{3}指正好3次
正则表达式的任何部分都可以用括号分组,然后作为一个单元处理

字符类
•使用方括号表示字符类
例如:类[abcde]将匹配单个字符,前提是它是列出的字符之一
可以使用连字符指定字符范围,例如。
⋄ [A-Z]大写罗马字母
⋄ [a-z]小写罗马字母
⋄ [A-Za-z]大写字母和小写字母
⋄ [0-9]位数0…9
⋄ [A-F]大写字母A…F
但要小心——最好坚持语义清晰的范围
⋄ OR可能会出现意外行为,例如。
⋄ [A-z]有效,但 /=[A-Za-z]
⋄ [a-Z]无效
⋄ [F-A]无效

示例:正则表达式“[a-d] [m-z] [0-9]*”
⋄ 匹配包含a和d之间任意字母的任何字符串
⋄ 后跟m和z之间的任何字母
⋄ 后跟0到9之间的零位或多位数字

一些常见的字符类具有预定义的名称:
. 匹配任何字符
\d 缩写[0-9]
\w 缩写[A-Za-z0-9_]
\s 缩写 [ \f\t\n\r]

要否定char类,请在开头加上“carat”符号ˆ
匹配除指定字符以外的任何内容:
[ˆabc] 除了abc以外的所有内容都匹配
[ˆ\d\s] 数字或空白不匹配
\D是\d反面;\W是\w反面;\S是\s反面

锚固件Anchors
•锚结匹配出现在特定位置:
⋄ ˆ匹配字符串的开头
⋄ $ 匹配字符串的结尾
⋄ \b在单词边界处匹配(在\w和\W之间)
“^author” 匹配以author开头的字符串;
“[^0-9]” 意思是否定
[0-9] 起始锚点(字符串必须以数字开头)
“»$” looks for » at end of string
“\bfu(n|nny)” 匹配fun, funny,不退还

原始字符串和文字元字符
•一些特殊字符,如\b,在Python中存在问题
⋄ 通常,在字符串中,\b表示“退格”
⋄ 要让Python在正则表达式中正确处理\b,必须标记它作为原始字符串
⋄ 原始字符串前面是r

funRE = re.compile(r"\bfu(n|nny)")

可以使用\将元字符“逃脱”回其原始含义" \ ^"

提取匹配零件
•常用方法:
⋄ 使用regex的括号部分,称为groups
⋄ 用数字标识不同的组
⋄ 从正则表达式的左侧开始计数“开”括号(从1开始)

在Python中,成功的正则表达式匹配将返回匹配对象:
⋄ 对象存储有关匹配的信息,匹配子串及其跨度
⋄ 使用对象的方法可访问的信息:group(返回整个正则表达式匹配的子字符串)、groups、span(返回完全匹配的开始/结束索引)

查找多个Regex匹配
•Python提供了同时查找多个匹配项的方法
•方法findall返回匹配列表,如果正则表达式没有组,则完整正则表达式(组0s)的匹配项列表,(即括号内的子部分); 组匹配的n元组列表(对于组1+),如果正则表达式有组
•方法finditer返回匹配对象,每个匹配一个

贪婪匹配Greedy Matching
•对于Python(和PERL),正则表达式的匹配是贪婪的
⋄ 总是使用最长的匹配字符串
⋄ 对于每个量化的子模式,尝试匹配最长的子串
⋄ 这并不总是你需要的行为
•示例:尝试创建用于捕获HTML标记的正则表达式

»> str =<p><b>hello</b></p>’
»> tag = re.compile(<.*>)
»> m = tag.search(str)
»> m.group()<p><b>hello</b></p>

可以通过添加“?”来强制量词的非贪婪匹配:
量词*?,+?,??,{m,n}?匹配最短字符串可进行整体匹配
示例:再次捕获HTML标记:

»> str =<p><b>hello</b></p>’
»> tag = re.compile(<.*?>)
»> m = tag.search(str)
»> m.group()<p>’
»> tag.findall(str)
[<p>’, ’<b>’, ’</b>’, ’</p>]

可以提供修改正则表达式编译方式的标志,从而修改它在匹配中的行为。

»> m = re.search([a-z]+’,str,re.IGNORECASE)
»> word = re.compile([a-z]+’,re.I)
»> firstword = re.compile(’^[a-z]+’,re.I|re.M)
»> str=’This and that.\nAnd the other.’
»> firstword.findall(str)
[’This’, ’And’]

进行替换
•关键操作是子串替换或替换
•对于Python中的替换,可以使用regex对象方法sub()
⋄ 具有用于替换字符串的参数,并且与之匹配的字符串
⋄ 可选关键字arg count=n设置的计数上限已替换–如果不存在(或计数=0),则替换所有出现的
⋄ 返回替换完成后产生的字符串

»> names = re.compile((Alan|Bill|Chad))
»> str = ’Vote for Alan. Bill is clever.’
»> names.sub(’Mark’,str)
’Vote for Mark. Mark is clever.’
»> names.sub(’Mark’,str,count=1)
’Vote for Mark. Bill is clever.’

替代方法sub(),返回(作为n元组),两者都已修改字符串和已完成的替换计数;相应的类级函数还将regex作为其第一个参数
•在构造替换字符串-用于反向引用(backreferences)
⋄ 反向引用的形式为“\N”,表示某些N≥ 1.
⋄ 指与正则表达式的第N组匹配的文本
⋄ 存在backref时必须使用原始字符串

»> swap = re.compile((Anne|Abi) (likes|hates) (Bill|Bob))
»> str = ’I heard that Anne likes Bill, today.’
»> swap.sub(r’\3 \2 \1’,str)
’I heard that Bill likes Anne, today.’

拆分和连接
•Python正则表达式具有拆分字符串的拆分方法:
⋄ 正则表达式匹配标识分割点
⋄ 拆分点之间的字符串将作为列表返回

»> tokenize = re.compile([^A-Za-z]+’)
»> str = ’I said, "No - go away!".’
»>tokenize.split(str)
[’I’, ’said’, ’No’, ’go’, ’away’, ”]

Python字符串是具有自己方法的对象。为了加入字符串列表,
从分隔符字符串的实例调用join()方法:

»> tokens=[’this’,’and’,’that’]
»> ’::’.join(tokens)
’this::and::that’

其他一些Python字符串方法对文本处理非常有用。
如果它们足以满足您的需求,则具有以下优势:
⋄ 比正则表达式更易于使用
⋄ 比正则表达式更快/更高效
⋄ 当读取代码时,方法名称提供了清晰的“语义”
•一些Python字符串方法示例:
⋄ 字符串测试方法,如:isupper(), islower(), isalpha(), isdigit(), isalnum()
⋄ 大写/小写转换,如:upper(), lower(), capitalize()
⋄ 拆分固定字符串(非正则表达式): split()

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值