设为首页 收藏本站
查看: 510|回复: 0

[经验分享] Python正则式初探

[复制链接]

尚未签到

发表于 2017-5-1 07:39:44 | 显示全部楼层 |阅读模式
先介绍下最常见的元字符metacharacter:
literal      匹配字符串的值    foo
re1|re2   匹配正则式re1或re2    foo|bar
.              匹配一个任何字符(换行符除外)  b.b
^              匹配字符串开始           ^Dear
$             匹配字符串结束            /bin/*sh$
*              匹配前面出现的零次或多次      [A-Za-z0-9]*
+             匹配前面出现的一次或多次       [a-z]+\.com
?             匹配前面出现的零次或一次       goo?
{N}          匹配前面出现的正则式N次         [0-9]{3}
{M,N}       匹配前面出现的M次到N次         [0-9]{5,9}
[...]          匹配字符组里出现任意一个字符        [aeiou]
[...x-y...]   匹配从字符x到y中的任意一个字符     [A-Za-z]
[^...]         匹配不在字符集中的任意一个字符     [^A-Za-z]
(*|+|?|{})? 用于上面出现的任何“非贪婪”版本重复匹配次数         .*?[a-z]
(...)          匹配封闭括号中的正则式,并保存为子组         ([0-9]{3})?
 
接下来再介绍几个特殊字符:
\d            匹配任何一个数字字符,和[0-9]一样,\D是\d的反义词,表示任何一个非数字字符       data\d+\.txt
\w            匹配任何一个数字字母下划线字符,和[A-Za-z0-9_]相同,\W跟\w相反      [A-Za-z_]\w+
\s             匹配任何一个空白符,和[\n\t\r\v\f ]相同, \S是\s的反义
\b             匹配单词边界,\B是\b的反义          \bThe\b
\nn           匹配已保存的子组          price:\16
\c             逐一匹配特殊字符c,即取消它的特殊含义,按字面匹配    \.    \\,    \*
\A(\Z)       匹配字符串的起始(结束),跟^$是意义一样
 
再用一张图解释全部:
DSC0000.png
 

  ★ re.compile(strPattern[, flag]):
  这个方法是Pattern类的工厂方法,用于将字符串形式的正则表达式编译为Pattern对象。
  第二个参数flag是匹配模式,取值可以使用按位或运算符'|'表示同时生效,比如re.I | re.M。
  另外,你也可以在regex字符串中指定模式,
  比如re.compile('pattern', re.I | re.M)与re.compile('(?im)pattern')是等价的。
  可选值有:
  re.I(全拼:IGNORECASE): 忽略大小写(括号内是完整写法,下同)
  re.M(全拼:MULTILINE): 多行模式,改变'^'和'$'的行为(参见上图)
  re.S(全拼:DOTALL): 点任意匹配模式,改变'.'的行为
  re.L(全拼:LOCALE): 使预定字符类 \w \W \b \B \s \S 取决于当前区域设定
  re.U(全拼:UNICODE): 使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性
  re.X(全拼:VERBOSE): 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。 
 
解释下“非贪婪”匹配?
当表示重复次数的元字符(*+?{m,n})单独使用时会尽量吸收更多的字符,一直吸到不匹配为止,榨干你丫的。哈哈哈。
而上面的(*+?{m,n})后面接了?后,就表示非贪婪匹配,匹配最短的,留下尽可能多的字符给后面的模式(如果存在)。
 
 使用compile()编译正则表达式后,将正则式模式编译成regex对象,以后重复使用这个对象的时候可以提升执行的性能。
 

m = re.match('\w\w\w-\d\d\d', 'abc-123')
if m is not None:
print(m.group())
m = re.match('\w+\w+\w+-\d\d\d', 'abc-123')
if m is not None:
print(m.group())
m = re.match('\w+?\w+?\w+?-\d\d\d', 'abc-123')
if m is not None:
print(m.group())
 
哥原本以为那啥\w+会做贪婪匹配,弄的后面的两个\w+没得匹配,但是三个结果都一样啊。神马原因?
请看下面的:

m = re.match(r'(\w+)(\w+)(\w+)-\d\d\d', 'abcdefgh-123')
if m is not None:
print(m.group())
print(m.group(1))
print(m.group(2))

  输出:
  abcdefgh-123
  abcdef
  g
  贪婪算法是:我前面的尽可能多的匹配更多,但是我会保证后面的也能匹配的前提下,自己捞的越多越好,这个就跟贪官一样,反正我给后面的那些平民百姓保本的东西,让他们饿不死就行,自己捞的越多越好,真他吗的黑心啊。
  所以第一组中的(\w+)匹配了abcdef,留下两个gh给后面去抢。每人分一个,最小满足后面的。
  来来来,再看几个例子:

import re
__author__ = 'Xiong Neng'
# group示例
data = 'Thu'
patt1 = r'^(\w{3})'
m = re.match(patt1, data)
print(m.group(1))
patt2 = r'^(\w){3}'
m = re.match(patt2, data)
print(m.group(1))
# 贪婪匹配
data = "Sat Mar 21 09:20:57 2009::spiepu@ovwdmrnuw.com::1237598457-6-9"
# 获取最后的那三个连字符连起来的三个数,
# 搜索比匹配更合适,因为不在开头
patt = r'\d+-\d+-\d+'
print(re.search(patt, data).group())  # 打印出  1237598457-6-9
# 使用匹配,必须用到group
patt = r'.+(\d+-\d+-\d+)'
print(re.match(patt, data).group(1))  # 打印出  7-6-9,知道贪婪的厉害了吧。哈哈
# 接下来使用非贪婪操作符?
patt = r'.+?(\d+-\d+-\d+)'
print(re.match(patt, data).group(1))  # 打印出  1237598457-6-9
# 只获取三个数的中间那个数字:
patt = r'-(\d+)-'
print(re.search(patt, data).group())   # 打印-6-
print(re.search(patt, data).group(1))  # 打印6
# 建议阅读Jeffrey E. F. Friedl编写的《精通正则表达式》(Mastering Regular Expression)
  最后是几个小练习:

# 匹配所有整形字符串
patt = r'\d+'
# 匹配长整形
patt = r'\d+[lL]'
# 匹配浮点型
patt = r'(-?(\d+\.\d*|\d*\.\d+))([eE]-?\d+)?'
print(re.match(patt, '-.2e-22').group())
print(re.match(patt, '23.23056e-23').group())
# 匹配所有复数
patt = r'(-?(\d+\.\d*|\d*\.\d+))([eE]-?\d+)?\s*[+-]\s*(\d+\.\d*|\d*\.\d+)([eE]-?\d+)?[jJ]'
print(re.match(patt, '-.2e-22   -   32.E21J').group())
print(-.2e-22    -    32.E21J)
  本人博客已搬家,新地址为:http://www.pycoding.com/

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-371429-1-1.html 上篇帖子: python解析json文件 下篇帖子: Python解决codeforces ---- 1
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表