玩命加载中...
# Python中的正则表达式 4个小节,预计用时**20分钟**。 正则表达(Regular Expression,或简称RegEx)是编程语言中用来搜索文本中格式匹配的重要手段。比如说判断一个字符串是否包含合法的Email地址、找到文本中电话号码形式的字符出现的位置等等。 本教程将教会大家如何在Python中使用正则表达。 本教程基于**Python 3.7**。 原创者:**[我小宋](http://sofasofa.io/user_profile.php?id=1005970)** | 修改校对:SofaSofa TeamM | ---- ### 0. 准备 Python3中有自带的正则表达模块`re`,和其他模块一样,我们只需要`import`即可加载。 ```python import re ``` 下面的小例子,就是查找字符串中所有的`in`。通常我们在正则表达的格式前面加上`r`,比如下面的`r"in"`。 ```python string = "Taiwan is a province in China." x = re.findall(r"in", string) print(x) ``` ['in', 'in', 'in'] ### 1. 入门正则表达式 正则表达式本身也是用字符串表示,通常在引号前加上`r`。我们首先了解如何用字符来描述字符。 <br><br> `\d`表示一个数字; `\w`表示一个数字、一个字母或者一个下划线; `\s`表示一个空格; `?`表示任意0个或者一个字符; `.`表示任意一个字符; `*`表示任意一个字符串,甚至可以是空字符串; `+`表示任意一个非空的字符串; `[]`表示一个集合。 下面的例子中`r"i\w\w"`表示一个长度为3的字符串,第一个字符为`i`,第二三个字符是一个字母或者数字或者下划线。 所以我们得到的结果是`int`和`ing`。 ```python string = "I'm interested in buying the new BMW i3 car." x = re.findall(r"i\w\w", string) print(x) ``` ['int', 'ing'] `r"i\d"`表示一个长度为2的字符,第一个字符为`i`,第二个字符是数字。 ```python string = "I'm interested in buying the new BMW i3 car." x = re.findall(r"i\d", string) print(x) ``` ['i3'] `r"\w*i\w*"`表示包含字母`i`的子字符串。 ```python string = "I'm interested in buying the new BMW i3 car." x = re.findall(r"\w*i\w*", string) print(x) ``` ['interested', 'in', 'buying', 'i3'] `r"\w*[abc]\w*"`表示包含字母`a`或者`b`或者`c`的子字符串。 ```python string = "I'm interested in buying the new BMW i3 car." x = re.findall(r"\w*[abc]\w*", string) print(x) ``` ['buying', 'car'] ### 2. [ ]集合的使用 上一个例子我们看到了集合符号`[ ]`的一个例子。其实集合还有更丰富的用法,例如: `[125]`表示`1`或者`2`或者`5`; `[3-7]`表示`3`到`7`的一个数字,也就是`3`、`4`、`5`、`6`、`7`; `[0-9+]`表示`0`到`9`的一个数字或者`+`; `[a-z]`表示`a`到`z`的一个小写字母; `[a-zA-Z]`表示`a`到`z`的或者`A`到`Z`的一个大写字母; `[^xyz]`表示除了`x`、`y`、`z`以外的任意一个字符; `[]{n}`表示一个长度为n的子字符串,每个字符都来自集合; `[]{n,m}`表示一个长度大于等于n小于等于m的子字符串,每个字符都来自集合。 `r"2[0-9]{3}"`表示以2开头的所有的四位数。下面的例子中,我们提取了句子中所有的年份。 ```python string = "克洛泽参加的4届世界杯中,他一共打入16球,其中2002世界杯5球,2006德国世界杯5球,2010南非世界杯4球,2014巴西世界杯2球。" x = re.findall(r"2[0-9]{3}", string) print(x) ``` ['2002', '2006', '2010', '2014'] ### 3. re中的常见方法 `re`中的常见用法有`re.search`、`re.match`、`re.findall`、`re.split`、`re.sub`。 #### 3.1 re.search `re.search(pattern, string)`是搜索`string`中符合`pattern`的第一个字符串,返回一个`SRE_Match`对象。下面的例子中,我们搜索句子中第一个的年份;如果没有找到,则返回None。 ```python string = "克洛泽参加的4届世界杯中,他一共打入16球,其中2002世界杯5球,2006德国世界杯5球,2010南非世界杯4球,2014巴西世界杯2球。" x = re.search(r"2[0-9]{3}", string) print('第一个年份:', x.group()) print('在string的范围:', x.span()) print('开头的位置:', x.start()) print('结束的位置(不包含):', x.end()) ``` 第一个年份: 2002 在string的范围: (24, 28) 开头的位置: 24 结束的位置(不包含): 28 #### 3.2 re.match `re.match(pattern, string)`是对`string`和`pattern`进行匹配,返回一个`SRE_Match`对象,如果匹配失败则返回None。`match`是`search`的特殊情况,`match`必须从`string`的第一个字符开始匹配,要求更严格。 ```python string = "克洛泽参加的4届世界杯中,他一共打入16球,其中2002世界杯5球,2006德国世界杯5球,2010南非世界杯4球,2014巴西世界杯2球。" x = re.search(r"2[0-9]{3}", string) if x: print('re.search成功') else: print('re.search失败') x = re.match(r"2[0-9]{3}", string) if x: print('re.match成功') else: print('re.match失败') ``` re.search成功 re.match失败 #### 3.3 re.findall `re.findall(pattern, string)`是从`string`找到所有符合`pattern`的子字符串,返回一个list,如果没有找到则返回一个空的list。 ```python string = "克洛泽参加的4届世界杯中,他一共打入16球,其中2002世界杯5球,2006德国世界杯5球,2010南非世界杯4球,2014巴西世界杯2球。" x = re.findall(r"2[0-9]{3}", string) print(x) ``` ['2002', '2006', '2010', '2014'] #### 3.4 re.split `re.split(pattern, string)`是从`string`找到所有符合`pattern`的子字符串,并以这些子字符串为切割点,对原字符串进行分隔,返回得到一个list,每个元素是被分割的子字符串。 如果没有找到则返回一个只包含`string`的list。 ```python string = "克洛泽参加的4届世界杯中,他一共打入16球,其中2002世界杯5球,2006德国世界杯5球,2010南非世界杯4球,2014巴西世界杯2球。" x = re.split(r"2[0-9]{3}", string) print(x) ``` ['克洛泽参加的4届世界杯中,他一共打入16球,其中', '世界杯5球,', '德国世界杯5球,', '南非世界杯4球,', '巴西世界杯2球。'] #### 3.5 re.sub re.split(pattern, replace, string)是查找替换的功能,从`string`找到所有符合`pattern`的子字符串,并替换成`replace`。 ```python string = "克洛泽参加的4届世界杯中,他一共打入16球,其中2002世界杯5球,2006德国世界杯5球,2010南非世界杯4球,2014巴西世界杯2球。" x = re.sub(r"2[0-9]{3}", "某某年", string) print(x) ``` 克洛泽参加的4届世界杯中,他一共打入16球,其中某某年世界杯5球,某某年德国世界杯5球,某某年南非世界杯4球,某某年巴西世界杯2球。 ### 4. 练习:利用Python正则表达判断合法Email地址 ```python def IsValidEmail(email): pattern = r"[a-zA-Z0-9_+\.-]+@\w+\.\w+" if not re.match(pattern, email): return False return True email1 = 'submit@sofasofa.io' print('Is %s valid? %s\n'%(email1, IsValidEmail(email1))) email2 = 'a?b@gmail' print('Is %s valid? %s\n'%(email2, IsValidEmail(email2))) email3 = '123@456@qq.com' print('Is %s valid? %s\n'%(email3, IsValidEmail(email3))) ``` Is submit@sofasofa.io valid? True Is a?b@gmail valid? False Is 123@456@qq.com valid? False <ul class="pager"> <li class="next"><a href="../../tutorials.php"><b><i class="fa fa-graduation-cap" aria-hidden="true"></i>&nbsp; 学完咯!</b></a></li> </ul>