Python的re,正则表达式,希望这次比较能让我记住里面的80%以上。(未完成,待继续)

re匹配www的url

'w{3}\.(?!-)[-A-Za-z0-9]{1,63}(?<!-)[.][A-Za-z]{2,}'

  

 

 

re(regex,regexp)是每个语言里面基本都会用到的,自己以前也一直看,看了忘,忘了看,希望这次写下博客,能够让自己思路清晰一点。

重点提醒,避坑:

使用Python原始字符串,建议再规则的地方前面加上r,禁止转义。

今天就上当了一个\b,\b在配制的时候,如果你默认啥参数不加,asci会匹配为退格符,你可以在\b之前再加\转义后面那个\实现你\b想要的效果。

但还是加r方便,这样的话,你再里面写什么都是re的规则,不用怕asci字符的影响,而且我测试了,好像也不影响\n的使用。建议没事就前面+r,禁止asci转义

 

首先,我先上re的模块函数:

re.compile:使用任何可选的标记来编译正则表达式的模式,然后返回一个正则表达式对象。(小提醒:re.compile里面设置了flags有效,通过re.compile后续进行查询,函数中的flags无效)

个人理解:生成一个re的pattern参数对象,使用后续我介绍的方法,该对象加函数,函数后面的参数里面pattren可以不用写。

re.compile的优势:能够提供预编译,预编译的话速度比较快,提升性能,所以进行多次比较操作,建议使用该函数。

re.pupge:清除隐式编译的正则表达式模式。因为模块函数会对已经编译的对象进行缓存,使用该方法可以进行缓存清除。

re.match(pattern,string,flags=0):从头部开始匹配字符串,如果匹配成功返回匹配对象,如果失败,就返回None。(只查找第一个

re.saerch(pattern,string,flags=0):全文开始匹配字符串,如果匹配成功返回匹配对象,如果失败,就返回None。(只查找第一个

 

参考链接:https://docs.python.org/zh-cn/3.8/howto/regex.html

这里有一个?!的特殊用法,用的很厉害,做个比较,有空可以回头来看

另一个零宽度断言是前向断言。 前向断言以正面和负面形式提供,如下所示:

(?=…)

正向前向断言。 如果包含的正则表达式,由 ... 表示,在当前位置成功匹配,则成功,否则失败。 但是,一旦尝试了包含的表达式,匹配的引擎就不会前进;模式其余的部分会在在断言开始的地方尝试。

(?!…)

负向前向断言。 这与积正向断言相反;如果包含的表达式在字符串中的当前位置  匹配,则成功。

更具体一些,让我们看看前向是有用的情况。 考虑一个简单的模式来匹配文件名并将其拆分为基本名称和扩展名,用 . 分隔。 例如,在 news.rc 中,news 是基本名称,rc 是文件名的扩展名。

与此匹配的模式非常简单:

.*[.].*$

请注意,. 需要特别处理,因为它是元字符,所以它在字符类中只能匹配特定字符。 还要注意尾随的 $;添加此项以确保扩展名中的所有其余字符串都必须包含在扩展名中。 这个正则表达式匹配 foo.barautoexec.batsendmail.cf 和 printers.conf

现在,考虑使更复杂一点的问题;如果你想匹配扩展名不是 bat 的文件名怎么办? 一些错误的尝试:

.*[.][^b].*$ 上面的第一次尝试试图通过要求扩展名的第一个字符不是 b 来排除 bat。 这是错误的,因为模式也与 foo.bar 不匹配。

.*[.]([^b]..|.[^a].|..[^t])$

当你尝试通过要求以下一种情况匹配来修补第一个解决方案时,表达式变得更加混乱:扩展的第一个字符不是 b。 第二个字符不 a;或者第三个字符不是 t。 这接受 foo.bar 并拒绝 autoexec.bat,但它需要三个字母的扩展名,并且不接受带有两个字母扩展名的文件名,例如 sendmail.cf。 为了解决这个问题,我们会再次使模式复杂化。

.*[.]([^b].?.?|.[^a]?.?|..?[^t]?)$

在第三次尝试中,第二个和第三个字母都是可选的,以便允许匹配的扩展名短于三个字符,例如 sendmail.cf

模式现在变得非常复杂,这使得它难以阅读和理解。 更糟糕的是,如果问题发生变化并且你想要将 bat 和 exe 排除为扩展,那么该模式将变得更加复杂和混乱。

负面前向消除了所有这些困扰:

.*[.](?!bat$)[^.]*$ 负向前向意味着:如果表达式 bat 此时不匹配,请尝试其余的模式;如果 bat$ 匹配,整个模式将失败。 尾随的 $ 是必需的,以确保允许像 sample.batch 这样的扩展只以 bat 开头的文件能通过。 [^.]* 确保当文件名中有多个点时,模式有效。

现在很容易排除另一个文件扩展名;只需在断言中添加它作为替代。 以下模块排除以 bat 或 exe:

.*[.](?!bat$|exe$)[^.]*$

 

 

 

 参考链接:https://docs.python.org/zh-cn/3.8/library/re.html#re.ASCII

(?=…)

匹配  的内容,但是并不消费样式的内容。这个叫做 lookahead assertion。比如, Isaac (?=Asimov) 匹配 'Isaac ' 只有在后面是 'Asimov' 的时候。

(?!…)

匹配  不符合的情况。这个叫 negative lookahead assertion (前视取反)。比如说, Isaac (?!Asimov) 只有后面  是 'Asimov' 的时候才匹配 'Isaac ' 。

(?<=…)

匹配字符串的当前位置,它的前面匹配  的内容到当前位置。这叫:dfn:positive lookbehind assertion (正向后视断定)。 (?<=abc)def 会在 'abcdef' 中找到一个匹配,因为后视会往后看3个字符并检查是否包含匹配的样式。包含的匹配样式必须是定长的,意思就是 abc 或 a|b 是允许的,但是 a* 和 a{3,4} 不可以。注意以 positive lookbehind assertions 开始的样式,如 (?<=abc)def ,并不是从 a 开始搜索,而是从 d 往回看的。你可能更加愿意使用 search() 函数,而不是 match() 函数:

>>>
>>> import re
>>> m = re.search('(?<=abc)def', 'abcdef')
>>> m.group(0)
'def'

这个例子搜索一个跟随在连字符后的单词:

>>>
>>> m = re.search(r'(?<=-)\w+', 'spam-egg')
>>> m.group(0)
'egg'

在 3.5 版更改: 添加定长组合引用的支持。

(?<!…)

匹配当前位置之前不是 ... 的样式。这个叫 negative lookbehind assertion (后视断定取非)。类似正向后视断定,包含的样式匹配必须是定长的。由 negative lookbehind assertion 开始的样式可以从字符串搜索开始的位置进行匹配。

今天总算有空可以看一下re,顺便翻了一下《Python核心编程》,书中内容还是非常不错的,只怪当年水平有限制没有看.

主要讲一些我对?= ?! ?<= 与?<!的一些理解,上面的是Python官网给的说明,示例比较少,我花了点时间,现在至少理解了。

 

首先这些只不过是放在匹配中的一些条件,单完全不会显式在匹配的信息中。

In [223]: re.search(r'(?=-)-egg', 'spam-egg')                                                                                                                        
Out[223]: <re.Match object; span=(4, 8), match='-egg'>  

 

我拿了官网的demo改了一下儿,很明显只有满足有-的条件才开始匹配,而且匹配点是从条件的满足点开始的。

理解了这个点,?<=属于先找出符合的条件,再向右边进行适配。

In [230]: re.search('123abc(?<=abc)def', '123abcdef')                                                                                                                
Out[230]: <re.Match object; span=(0, 9), match='123abcdef'>

In [231]: re.search('(?<=abc)def', 'abcdef')                                                                                                                         
Out[231]: <re.Match object; span=(3, 6), match='def'>

  

一个是从从左往右进行适配,一个是从右往左进行适配,虽然理解了具体的规则,但使用的话,还要进行多的锻炼

 

posted @ 2019-11-11 03:51  就是想学习  阅读(224)  评论(0编辑  收藏  举报