正则表达式-入门初探

最近处理数据,看开源代码满屏幕的正则表达式,脑壳疼。

花了一整天时间看 菜鸟教程 的正则表达式……感觉写的有点过于详细,而且顺序也让我很迷惑……

于是自己写点总结吧。

  • 我觉得首先要搞懂的是,正则表达式其实就是一个字符串的模板,用来在字符串中寻找符合条件的子串。下面是一个最简单的例子,用来在字符串中寻找‘1234’子串。
import re

myre = re.compile(r'1234')

mystr = 'xx1234yy'

myres = myre.search(mystr)

print(myres)

'''
<_sre.SRE_Match object; span=(2, 6), match='1234'>
'''
start
  • 相信大家开始学正则表达式的时候,肯定是突然有一个某个需求,然后找到其他人的代码,又想看懂吧。里面肯定各种大中小括号,让人头大2333333

不过先别急,先给出两个简单的概念,普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。

所谓的特殊字符(元字符),其实就是一些字符给了一些特殊的意义,有点类似于保留字、系统自带函数之类的东西,而且不允许你重载它。如果你想在正则表达式中匹配特殊字符本身,只需要在它之前加一个就行了,比如*就是匹配的*,但是单独的*就会发挥它的特定功能。具体有哪些特殊字符,可以参考这个菜鸟教程网页 。刚开始学没必要把它们都弄懂,只要把  + * 大中小括号先弄懂,就能写一些基本的正则表达式了。其他的后续碰到再查表就是了。

  • 我觉得有必要先弄懂大中小括号。
  • 先讲中括号[],中括号是一个字符簇。中括号要注意的就是,一个中括号虽然可以表达一个很大的范围(字符簇),但是它只能在字符串中匹配单一的一个字符。

    看下面的例子。

r'[AaEeIiOoUu]'
#这个模式与任何单个的元音字符匹配,但只能匹配一个字符。

#用连字号-可以表示一个字符的范围,如下
r'[a-z]' #匹配所有的单个小写字母 
r'[A-Z]' #匹配所有的单个大写字母 
r'[a-zA-Z]' #匹配所有的单个字母 
r'[0-9]' #匹配所有的单个数字 
r'[0-9.-]' #匹配所有的单个数字或句号或减号 
#需要匹配连续的某字符簇的话,配合+或者*使用。如下

r'[0-9]+'  #匹配0个或者连续多个0-9范围内的数字, 如‘1234’  或者 ‘’
r'[0-9]*'  #匹配至少1个或连续多个0-9范围内的数字, 如‘1234’
[]

         看完这个中括号的例子,大概也能猜到+ 和*的作用了。

  • 然后是小括号(),小括号是用来标记一个子表达式的开始和结束位置。
In [50]: myre = re.compile(r'([0-9][a-c])+')

In [51]: mystr = '1c2a3b'

In [52]: myres = myre.search(mystr)

In [53]: print(myres)
<_sre.SRE_Match object; span=(0, 6), match='1c2a3b'>

In [54]: myre2 = re.compile(r'[0-9][a-c]+')

In [55]: mystr2 = '1abbc'

In [56]: myres2 = myre2.search(mystr2)

In [57]: myres2
Out[57]: <_sre.SRE_Match object; span=(0, 5), match='1abbc'>

In [58]: myres3 = myre2.search(mystr)

In [59]: myres3
Out[59]: <_sre.SRE_Match object; span=(0, 2), match='1c'>
()

这个例子解释了加()对+元字符的作用范围的功能。不加()的时候,只能匹配数字开头,至少1个abc的字符串。但是加了()之后,变成了匹配数字和abc交替出现的字符串。

  • 然后是大括号{}, 大括号是用来标记前一个子表达式匹配的次数,其实作用和+ * 有些类似,只不过有特定的次数。看下面的例子:
'''
一个数字 {x} 的意思是前面的字符或字符簇只出现x次 ;一个数字加逗号 {x,} 的意思是前面的内容出现x或更多的次数 ;两个数字用逗号分隔的数字 {x,y} 表示 前面的内容至少出现x次,但不超过y次。我们可以把模式扩展到更多的单词或数字:
'''
r'a{4}'        #匹配连续4个a
r'a{2,}'      #匹配连续两个a的字符串
r'a{2,4}'     #匹配连续a,至少两个,最多4个。
{}

其实特殊字符 * 与 {0,} 是相等的,它们都代表着 0 个或多个前面的子表达式 。特殊字符 + 与 {1,} 是相等的,表示 1 个或多个前面的子表达式。 

我的入门初探小结大概就是这样了。能看懂上面这些的话,基本的正则表达式都能看懂了。

看教程的过程中还看到一个  “贪婪”“非贪婪”的概念。

这个东西其实也很好理解。下面给一个例子吧。

_curly_re = re.compile(r'(.*?){(.+?)}(.*)')


# 这个表达式,用小括号()分成了3部分,然后中间还有夹杂着{ }用来匹配左右大括号字符,而不是表示特殊符号大括号。

#第一个小括号中的子表达式:
#.表示通配符,匹配除换行符 
 之外的任何单个字符。
#.后面加了一个*,表示匹配前面的子表达式零次或多次
#.*结合起来就是匹配任意的符号0次或多次。
#但是后面又加了一个?     这个?就是标志 非贪婪的匹配。
# 什么叫非贪婪呢?

#举例如下
r'.*{'      #可以匹配'asdf{asdf{'
r'.*?{'      #只能匹配到'asdf{xxx{'中的  'asdf{'子串

#很好理解了吗? 非贪婪就是  .*对于这种可以无限往下匹配的表达式,会考虑后续表达式的匹配,而不是贪婪的无穷的匹配下去。
贪婪、非贪婪
原文地址:https://www.cnblogs.com/chengebigdata/p/9218148.html