正则表达式
1>概念:正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式就是记录文本规则的代码。
所以正则表达式并不是python中特有的功能,它是一种通用的方法。python中的正则表达式库,所做的事情是利用正则表达式来搜索文本。要使用它,你必须会自己用正则表达式来描述文本规则
4>字符匹配(普通字符,元字符):
普通字符:大多数数字和字母的任意集合
元字符:在正则表达式中具有特殊意义的专用字符
5>元字符
. :匹配除换行符以外的任意字符
^ :匹配字符串的开始(从字符串开头开始匹配)…………放到集合中的时候表示“非”
$ : 匹配字符串的结尾(从字符串的结尾开始匹配)
* : 匹配前面的子表达式零次或多次…………po*等价于子表达式可能是p、po、poo、pooo.......
+ :匹配前面的子表达式一次或多次…………po+等价于子表达式可能是po、poo、pooo.......
? :匹配前面的子表达式零次或一次…………po?等价于子表达式可能是p、po
| :将俩个匹配条件进行逻辑“或”运算
\ :反斜杠后面跟元字符去除其特殊功能
反斜杠后面跟普通字符实现特殊功能
引用序号所对应的字组所匹配的字符串…………re.search(r"(alex)(eric)com\2","alexericcomeric")
\d :匹配任意一个数字字符…………相当于[0-9]
\D :匹配任意一个非数字字符………相当于[^0-9]
\s :匹配任意一个不可见字符,包括空格、制表符、换页符等等…………等价于[ \t\n\r\f\v]
\S :匹配任意一个可见字符…………等价于[^ \t\n\r\f\v]
\w :匹配任意一个字母或数字或下划线或汉字…………等价于[a-zA-Z0-9_]
\W :匹配任意一个非字母或数字或下划线或汉字…………等价于[^a-zA-Z0-9_]
\b :匹配一个单词边界,也就是指单词和空格间的位置。
\n :匹配一个换行符
\f :匹配一个换页符
\r :匹配一个回车符
[a-z] :匹配括号中所包含的任意一个字符………-表示范围
[^a-z] :匹配任何不在指定范围内的字符…………其中^表示非得意思
[] :表示一个字符集,特殊字符在字符集中会失去其特殊意义(“^” 在字符集中是非得意思 “-”在字符集中是至的意思 “\d” "\w"等等还保留其原有意义)
{n} :n是一个非负整数 ,匹配整数n次
{n,} :n是一个非负整数,至少匹配n次
{n,m} :m,n均为非负整数,m>n,最少匹配n次,最多匹配m次
() :表示分组,利用findall匹配时,只输出的组里面的内容,并组成一个新组放到列表中
利用search和match匹配时,输出全部内容,可以用group方法取出来各个组的内容
1,字符组:[字符组]
在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示;
字符分为很多类,比如数字、字母、标点等等;
假如你现在要求一个位置“只能出现一个数字”,那么这个位置上的字符只能是0,1,2 . . . 9这10个数之一。
正则 |
待匹配的字符 |
匹配结果 |
说明 |
[0123456789] |
8 |
True |
在一个字符组里枚举合法的所有字符,字符组里的任意一个字符和“待匹配字符”相同都视为可以匹配 |
[0123456789] |
a |
False |
由于字符组里没有“a”字符,所以不能匹配 |
[0-9] |
7 |
True |
也可以用-表示范围,[0-9]就和[0123456789]是一个意思 |
[a-z] |
s |
True |
同样的如果要匹配所有的小写字母,直接用[a-z]就可以表示 |
[A-Z] |
B |
True |
[A-Z]就表示所有的大写字母 |
[0-9a-fA-F] |
e |
True |
可以匹配数字,大小写形式的a-f,用来验证十六进制字符 |
2,元字符
元字符 |
匹配内容 |
元字符 |
匹配内容 |
\w |
匹配字母或数字或下划线 |
\W |
匹配非字母或数字或下划线 |
\d |
匹配数字 |
\D |
匹配非数字 |
\s |
匹配任意空白(含换行,制表符,空格) |
\S |
匹配非空白符 |
\n |
匹配一个换行符 |
. |
匹配除换行符意外的任意字符 |
\t |
匹配一个制表符 |
a|b |
匹配字符a或字符b |
\b |
匹配一个单词的边界 |
() |
匹配括号内的表达式,也表示一个组 |
^ |
匹配字符串的开始 |
[…] |
匹配字符组中的字符 |
$ |
匹配字符串的结尾 |
[^…] |
匹配除了字符组中字符的所有字符 |
注意:1,有一些有特殊意义的元字符进入字符组中会恢复它本来的意义:有 . | ( ) [ ] 。
2,a|b表示符合a规则的或者b规则的都可以被匹配(如果a规则是b规则的一部分,且a规则比b规则要苛刻/要更长,就把a规则写在前面,即将更复杂的\更长的规则写在最前面)。
3,() 分组,表示给几个字符加上量词约束的需求的时候,就给这些量词分在一个组。
3,量词
量词 |
用法说明 |
量词 |
用法说明 |
{n} |
这个量词之前的字符重复n次 |
? |
这个量词之前的字符重复0次或1次 |
{n,} |
这个量词之前的字符重复n次或更多次 |
+ |
这个量词之前的字符重复1次或更多次 |
{n,m} |
这个量词之前的字符重复n到m次 |
* |
这个量词之前的字符重复0次或更多次 |
4,练习题
1) 匹配整数 \d+
2) 匹配小数 \d+\.\d+
3) 匹配小数或者整数 \d+\.\d+|\d+ 或 \d+(\.\d+)?
4) 匹配身份证号码(18位最后一位是数字或者x,15位数字)
[1-9]\d{16}[\dx]|[1-9]\d{14} 或 [1-9]\d{14}(\d{2}[\dX])?
5,正则表达式的匹配特点:贪婪匹配,即在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配。
非贪婪模式(也叫惰性匹配)则需要在量词的后面加上量词?
正则 |
待匹配字符 |
匹配结果 |
说明 |
<.*> |
<script>…<script> |
<script>…<script> (一条结果) |
默认为贪婪模式,会匹配尽量长的字符串 |
<.*?> |
<script>…<script> |
<script> <script> (两条结果) |
加上?会将贪婪匹配模式转为非贪婪匹配模式,会匹配尽量短的字符串 |
几个常用的非贪婪匹配:
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复
. *?的用法:
. 是任意字符
* 是取 0 至 无限长度
? 是非贪婪模式。
放在一起就是取尽量少的任意字符,一般不会这么单独写,他大多用在: .*?x 就是取前面任意长度的字符,直到一个x出现。
6,转义符
在正则表达式中,有很多有特殊意义的是元字符,比如\d和\s等,如果要在正则中匹配正常的"\d"而不是"数字"就需要对"\"进行转义,变成'\\'。
在python中,无论是正则表达式,还是待匹配的内容,都是以字符串的形式出现的,在字符串中\也有特殊的含义,本身还需要转义。所以如果匹配一次"\d",字符串中要写成'\\d',那么正则里就要写成"\\\\d",这样就太麻烦了。这个时候我们就用到了r'\d'这个概念,此时的正则是r'\\d'就可以了。
正则 | 待匹配字符 | 匹配结果 | 说明 |
\d | \d | False | 因为在正则表达式中\是有特殊意义的字符,所以要匹配\d本身,用表达式\d无法匹配 |
\\d | \d | True | 转义\之后变成\\,即可匹配 |
"\\\\d" | '\\d' | True | 如果在python中,字符串中的'\'也需要转义,所以每一个字符串'\'又需要转义一次 |
r'\\d' | r'\d' | True | 在字符串之前加r,让整个字符串不转义 |
关于字符串挪到python中的转义的问题 : 只需要在工具中测试完毕,确认可以匹配上之后,挪到python中在字符串的外面加上r(r””)即可。
7,总结:
普通字符就表示一个正常的字符;
元字符表示它特殊的意义 如果转义元字符,那么这个元字符就失去了特殊意义;
几个字符的组合关系:
字符/元字符 只约束一个字符
字符+量词 约束一个字符连续出现的次数
字符+量词+? 约束一个字符连续出现的最少次数
字符+量词+?+x 约束一个字符连续出现量词范围内的最少次数,遇到x就立即停止