正则表达式
首先需要指出的是:正则表达式是独立于所有编程语言存在的一种规范。任何一种编程语言都免不了要处理各种规范以及不规范的字符,例如:一个简单的用户登陆界面就要求用户输入:用户名、密码等,然后后台程序除了需要对输入的字符串做一些合法性的判断,例如不能出现特殊字符等。正则表达式就帮助我们能快速的处理这些字符串,得到它们是否合法。
python中内置了re模块,其中最常用的就是它的match()和group()方法,
match():判断待检测的字符是不是有符合正则表达式表达的部分,如果存在返回匹配到的对象,否则返回None;
group():方法在match返回值的基础上能得到待检测字符串中实际符合正则表达式规则的部分;
如下面的例子:
#在ipython的交互式操作终端中更容易展示正则表达式的效果
In [1]: import re
In [2]: result = re.match('hello','helloworld')
#match方法的第一个参数是正则表达式的实际形式,如hello,就是要检测待检测的字符串中是否有hello
#第二个参数是待检测的字符串
#result是match的返回结果,如果匹配成功否则返回None
In [3]: print(result)
<re.Match object; span=(0, 5), match='hello'>
In [4]: result.group()
Out[4]: 'hello'
正则表达式的语法
单个字符表示法
\d | 表示0-9的任意一个数字 |
\D | 表示任意一个非数字 |
\s | 表示任意一个空白字符,如:\n \r Tab等 |
\S | 表示任意一个非空白的字符 |
\w | 表示任意一个单词字符,包括a-z,A-Z,0-9,_ |
\W | 表示任意非单词的一个字符 |
. | 表示任意一个字符,除了\n |
[] | 表示[]中的任意一个字符 |
代码:
# .
In [5]: result = re.match('.','a')
In [6]: result.group()
Out[6]: 'a'
In [7]: result = re.match('.','aa')
In [8]: result.group()
Out[8]: 'a'
In [9]: result = re.match('.','abc')
In [10]: result.group()
Out[10]: 'a'
In [13]: result = re.match('...','abc')
In [14]: result.group()
Out[14]: 'abc'
In [15]: result = re.match('....','abc')
In [16]: print(result)
None
#从以上的测试可以看出
#(1)match()方法默认从左向右依次匹配;
#(2)匹配的时候会先看看正则表达式实际可能表达几个字符,如果待检测的字符多于正则表达式之际表示的字符才会进行后续的匹配,否则直接返回None,例如最后的的三个: ....实际表达4个字符,但是待检测字符之后三个,因此返回None;
#(3)匹配的时候从左向右依次匹配,如果匹配到了结果就不再进行匹配了。
# \d \D
In [17]: result = re.match('\d','1')
In [18]: result.group()
Out[18]: '1'
In [20]: result = re.match('\D','1')
In [22]: print(result)
None
In [23]: result = re.match('\D','a')
In [24]: result.group()
Out[24]: 'a'
#\s \S
In [25]: result = re.match('\s','\n')
In [26]: result.group()
Out[26]: '\n'
In [27]: result = re.match('\s','\r')
In [28]: result.group()
Out[28]: '\r'
In [33]: result = re.match('\S','1')
In [34]: result.group()
Out[34]: '1'
# \W \w
In [35]: result = re.match('\w','1')
In [36]: result.group()
Out[36]: '1'
In [37]: result = re.match('\w','a')
In [38]: result.group()
Out[38]: 'a'
In [39]: result = re.match('\w','A')
In [40]: result.group()
Out[40]: 'A'
In [41]: result = re.match('\w','_')
In [42]: result.group()
Out[42]: '_'
In [43]: result = re.match('\w','$')
In [44]: print(result)
None
In [47]: result = re.match('\W','$')
In [48]: result.group()
Out[48]: '$'
#[]
In [49]: result = re.match('[abc@#$%)(*&^]','a')
In [50]: result.group()
Out[50]: 'a'
In [51]: result = re.match('[abc@#$%)(*&^]','1')
In [52]: print(result)
None
In [53]: result = re.match('[a-zA-Z0-9]','#')
In [54]: print(result)
None
In [55]: result = re.match('[a-zA-Z0-9]','1')
In [56]: print(result)
<re.Match object; span=(0, 1), match='1'>
In [57]: result.group()
Out[57]: '1'
#[]里面可以存放单个的字符,也可以存放一个范围如1-9,每个范围、字符之间要紧挨着写
字符个数表示法
* | 表示前一个字符出现0次或者无限次,即可有可无 |
+ | 表示前一个字符出现1次或者无限次,即至少有1次 |
? | 表示前一个字符出现1次或者0次,即要么有1次,要么没有 |
{m} | 表示前一个字符出现m次 |
{m,} | 表示前一个字符至少出现m次 |
{m,n} | 表示前一个字符出现从m到n次 |
In [58]: result = re.match('\d*','')
In [59]: result.group()
Out[59]: ''
In [60]: result = re.match('\d?','1')
In [61]: result.group()
Out[61]: '1'
In [62]: result = re.match('\d+','321')
In [63]: result.group()
Out[63]: '321'
In [64]:
In [64]: result = re.match('\d{3}','321')
In [65]: result.group()
Out[65]: '321'
In [66]: result = re.match('\d{3}','321123')
In [67]: print(result)
<re.Match object; span=(0, 3), match='321'>
In [68]: result.group()
Out[68]: '321'
In [69]: result = re.match('\d{3}','32')
In [70]: print(result)
None
In [71]: result = re.match('\d{3,}','328768787')
In [72]: print(result)
<re.Match object; span=(0, 9), match='328768787'>
In [73]: print(result)
<re.Match object; span=(0, 9), match='328768787'>
In [74]: result.group()
Out[74]: '328768787'
In [75]: result = re.match('\d{3,6}','3285430985908')
In [76]: print(result)
<re.Match object; span=(0, 6), match='328543'>
In [77]: result = re.match('\d{3,6}','3a285430985908')
In [78]: print(result)
None
边界表示法
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
\b | 匹配一个单词的边界,单词指:字母数字或下横线字符 |
\B | 匹配非单词边界 |
In [79]: result = re.match('^\d','333333333')
In [80]: result.group()
Out[80]: '3'
In [81]: result = re.match('^\d*','333333333')
In [82]: result.group()
Out[82]: '333333333'
In [83]: result = re.match('^\d*!$','333333333')
In [85]: print(result)
None
In [86]: result = re.match('^\d*!$','333333333!')
In [87]: print(result)
<re.Match object; span=(0, 10), match='333333333!'>
In [88]: result.group()
Out[88]: '333333333!'
原始字符串
当一个字符串内容是 ‘\nhello\n’ 的时候,直接输出的结果是:先换行,然后是hello,最后再换行。如果就行要原原本本地输出这个字符串本身,那么就要在\前加\,表示转义字符。
In [89]: str1 = '\nhelle\n'
In [90]: str1
Out[90]: '\nhelle\n'
In [91]: print(str1)
helle
In [92]: str2 = '\\nhello\\n'
In [93]: print(str2)
\nhello\n
In [94]: str3 = r'\nhello\n'
In [95]: print(str3)
\nhello\n
同理,当正则表达式本身需要转移时同样可以使用r,且因为正则表达式本身可能有\s\W\d等多个这样的字符组成,因此通常在正则表达式前都加r。
In [98]: result = re.match(r'\n\d','\n1')
In [99]: result.group()
Out[99]: '\n1'