python 正则表达式语法

正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。

例如:

  • runoo+b,可以匹配 runoob、runooob、runoooooob 等,+ 号代表前面的字符必须至少出现一次(1次或多次)。
  • runoo*b,可以匹配 runob、runoob、runoooooob 等,* 号代表字符可以不出现,也可以出现一次或者多次(0次、或1次、或多次)。
  • colou?r 可以匹配 color 或者 colour,? 问号代表前面的字符最多只可以出现一次(0次、或1次)。

构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与运算符可以将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。

正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为"元字符")组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。

官方解释:正则表达式的概念是使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串

简单来说,正则表达式就是通过一定的匹配规则,从一个字符串中提取出我们想要的数据,虽然有时候会比较复杂,但无疑它是非常强大的。

在python中要使用正则表达式,首先需要先导入python内置的re模块。

正则表达式的灵魂在于匹配规则的灵活使用,而匹配规则,我简单将之分为两大类,一类是普通字符,这类匹配意义往往不大,另一类是元字符,是我们需要重点掌握的内容。

我们先来用代码示例来看看普通字符的匹配:

import re
target = 'life is short, i learn python.'
result = re.findall('python', target)
# findall是re库的一个重要方法,第一个参数是匹配规则,第二个参数是要匹配的目标字符串,还有第三个参数,我们之后讲,findall返回的结果是一个列表。
# 这行代码的意思是从target中匹配'python',如果匹配到就返回,没有匹配到就返回空列表。
result1 = re.findall('java', target)
print(result)
# 得到的结果是['python']
print(result1)
# 得到的结果是[]

如果匹配规则是一个普通字符串的话,意义并不大,试想一下,一个网页上的内容都是变化的,处处可能都不一样,我们想用一个固定的普通字符串去匹配到内容,显然是不太合适的。

就比如简书网站,我们想要获取每篇文章的发布时间,每篇的文章的发布时间都是不一样的,用一个固定的字符串显然匹配不出来我们想要的内容。

但是,通过上述的匹配,我们能够联想到我们之前学过的什么内容吗?有关于字符串的。

if in,是不是?判断一个字符串是否存在于另一个字符串中。我们就可以用上述代码来自己实现这个功能,有兴趣的童鞋可以自己尝试封装成一个函数。

接下来,就是我们的重头戏了,元字符,我粗略地将他们分为了7类,我们先来看第一类,字符集,用[]表示,中括号内可以写任意字符,各字符间是或的关系(不理解没关系,后面会有代码解释):

现在我们得到了一个这样的字符串 target = ‘abc acc aec agc adc aic’,我们有这样一个需求,需要找出这个字符串中中间是d或者e的单词,我们该怎么做呢?

import re
target = 'abc acc aec agc adc aic'
result = re.findall('a[de]c', target)
# 这一行中的[de]表示这个位置上的字符是d或者是e都可以匹配出来
print(result)
# 得到的结果是['aec', 'adc']

这只是字符集[]的一个最简单的应用,现在我们又有一个需求,需要找出这个字符串中中间是b-z之间的任意一个字符的单词,就可以这样写了,而不需要把b-z之间的字符都写出来。

import re
target = 'abc acc aec agc adc aic'
result = re.findall('a[b-z]c', target)
# 这一行中的[b-z]表示这个位置上的字符在b-z范围内都可以匹配出来
print(result)
# 得到的结果是['abc', 'acc', 'aec', 'agc', 'adc', 'aic']

还有另一种用法需要了解,我们同样还是通过代码来理解比较好。

import re
target = 'abc acc aec agc adc aic'
result = re.findall('a[^c-z]c', target)
# 这一行中的[^c-z]表示这个位置上的字符不在c-z范围内都可以匹配出来,注意是不在
print(result)
# 得到的结果是['abc']

好了,字符集[]的匹配规则就讨论完了,我们来总结下:

我们来讨论第二类匹配规则,我称之为“概括字符集”,主要讨论以下六种:

通过上述六个简单的例子,就能发现,单个地使用概括字符集意义并不大,无法达到我们想要的效果,往往需要结合数量词来使用,才会发挥出最大的效用。

接下来,我们来看看第三类匹配规则——数量词,并结合第二类概括字符集来实现某些功能:

假设现在我们获取到了一本英文书的全部内容,想要判断这本书有多少字数,该怎么做呢?

还是老规矩,我们通过代码来解释:

上述代码还是存在某些缺陷,万一某个英文单词的长度超过30了怎么办?所以我们应该换种方式来写:

再来看一个很实用的例子,提取文章的点赞数或者评论数等等:

至此,数量词我们已经讨论了{}和+,至于?和*,我们放在后面和贪婪与非贪婪一起讲,因为?和*还有.经常连在一起使用。

今天的最后,我们再来讨论第四类匹配规则,边界匹配符:

通过上述例子,我们能发现^其实就相当于我们之间讲的字符串的一个方法,叫做startswith。

同样的,有startswith,当然会有类似于endswith的匹配规则,我们用代码来看下:

好啦,今天的分享就到这里结束了,我们明天来分享剩下的三类匹配规则,大家要动手实践哦,知识只有应用起来才能体现它存在的价值。

 

 

更多语法:请参考:http://www.runoob.com/regexp/regexp-syntax.html

点赞

发表评论