什么是正则表达式
基本说来,正则表达式是一种用来描述一定数量文本的模式。Regex代表Regular Express。我们使用一种自定义的模式来匹配一定数量的文本,并从中提取所需数据。如同window的通配符,如:.txt查找所有txt文件。就被解释成任意字符。
python中的正则表达式大致分为以下几部分:
- 元字符
- 模式
- re 内置对象用法
所有关于正则表达式的操作都使用 python 标准库中的 re 模块。
Python中的re模块
import re # 导入re模块
dir(re) # 查看re模块的方法和属性
['A', 'ASCII', 'DEBUG', 'DOTALL', 'I', 'IGNORECASE', 'L', 'LOCALE', 'M', 'MULTILINE', 'RegexFlag', '
S', 'Scanner', 'T', 'TEMPLATE', 'U', 'UNICODE', 'VERBOSE', 'X', '_MAXCACHE', '__all__', '__builtins_
_', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__ver
sion__', '_alphanum_bytes', '_alphanum_str', '_cache', '_compile', '_compile_repl', '_expand', '_loc
ale', '_pattern_type', '_pickle', '_subx', 'compile', 'copyreg', 'enum', 'error', 'escape', 'findall
', 'finditer', 'fullmatch', 'functools', 'match', 'purge', 'search', 'split', 'sre_compile', 'sre_pa
rse', 'sub', 'subn', 'template']
一、常见的元字符及用法
元字符 | 表述 | 表达式示例 | 完整匹配的字符串 |
---|---|---|---|
. | 匹配任意字符(不包括换行符\n) | a.c | abc |
\ | 转义字符,使跟在其后的字符将失去作为特殊元字符的含义例如\.只能匹配.,不能再匹配任意字符 | a.c | a.c |
[...] | 字符集,一个字符的集合,可匹配其中任意一个字符 | a[bcd]e | abe/ace/ade |
预定义字符(可以写在字符集[...]) | |||
\d | 匹配一个数字 [0-9] | a\dc | a1c |
\D | 匹配非数字 [^0-9]|[^\d] | a\Dz | ajz/a z/a*z/... |
\s | 匹配任意空白字符 [<空格> \t\n\r\f\v] | a\sc | a c/a\t/a\n/... |
\S | 匹配非空白字符[^ \t\n\r\f\v]]|[^\s] | a\Sc | axc/a>c/a水c/... |
\w | 匹配数字、字母、下划线中任意一个字符[a-zA-Z0-9_] | a\wc | aac/aZc/a3c/a_c |
\W | 匹配非数字、字母、下划线中的任意字符 [^a-zA-Z0-9_] | a\Wc | a c/a得c/a+c/... |
数量词(用在字符或(...)之后) | |||
* | 匹配前一个元字符0到多次 | abc* | ab/abcccc |
+ | 匹配前一个元字符1到多次 | abc+ | abc/abccc |
? | 匹配前一个元字符0到1次 | goo? | goo/go |
{m} | 匹配前一个元字符m次 | a{3} | aaa |
{m,n} | 匹配前一个元字符m到n次 | [0-9]{2,5} | 11/1111/11111 |
*?/+?/??/{m,n}? | 使*?/+?/??/{m,n}?变成非贪婪模式 | 示例参照下文 | |
边界匹配(不消耗待匹配字符串中的字符) | |||
^ | 匹配开始位置,多行模式下匹配每一行的开始 | ^Dear | Dear |
[^x] | 匹配除了x以外的任意字符 | [^abcd] | a |
$ | 匹配结束位置,多行模式下匹配每一行的结束 | .*sh$ | wddefsh |
\b | 匹配一个单词边界,匹配\w和\W之间的单词也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”(与\B相反) | a\b!ac | a!ac |
\B | 匹配非单词边界 [^\b] “er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er” | a\Bss | ass |
\A | 匹配字符串开始位置,忽略多行模式 | \ADear | Dear |
\Z | 匹配字符串结束位置,忽略多行模式 | .*ar\Z | ar/sffar |
逻辑分组 | |||
| | 代表左右表达式任意匹配 “或” 他总是先匹配 |左边的表达式,一旦满足条件则直接跳过右边的条件 如果|没有在()则他的范围是整个表达式 | abc|def | abc/def |
(...) | 分组,默认为捕获,即被分组的内容可以被单独取出,默认每个分组有个索引,从 1 开始,按照"("的顺序决定索引值 | ([0-9]{3})f(oo l u)bar | 234foobar/012fubar |
(?P |
分组的命名模式,取此分组中的内容时可以使用索引也可以使用name | (?P |
abdabd |
\ |
引用 |
(\d)abd\1 | 1abd1/4abd4 |
(?P=name) | 分组的引用模式,可在同一个正则表达式用引用前面命名过的正则 | (?P |
1abc1/4abc4 |
特殊构造(不作为分组) | |||
(?iLmsux) | 分组中可以设置模式,iLmsux之中的每个字符代表一个模式,只能用在正则表达式的开头用法参见 模式 1 | (?abc) | AbC |
(?:...) | 分组的不捕获模式,计算索引时会跳过这个分组 | (?:abc){2} | abcabc |
(?#...) | 注释,不影响正则表达式其它部分 | abc(?#coment)123 | abc123 |
(?=...) | 之后的字符串内容需要匹配表达式才能成功匹配。不消耗字符串内容 | a(?=\d) | a后面是数字 |
(?!...) | 之后的字符串内容需要不匹配表达式才能成功匹配。不消耗字符串内容。 | a(?!\d) | a后面不能是数字 |
(?<=...) | 之前的字符创内容需要匹配表达式才能成功匹配。不消耗字符串内容 | (?<=\d)a | 前面是数字的a |
(? | 之前的字符创内容需要不匹配表达式才能成功匹配。不消耗字符串内容 | (?!=\d)a | 前面不是数字的a |
(?(id/name)yes | no) 若前面指定id或name的分区匹配成功则执行yes处的正则,否则执行no处的正则 | (\d)abc(?1)\d|abc) | 1abc2/abcabc |
\number | 匹配和前面索引为number的分组捕获到的内容一样的字符串 |
重复与贪婪重复和惰性重复
重复的含义是指重复匹配满足某一匹配模式的文本。
如例中(匹配ip)的’?’号就是一个重复的例子,它的含义是某一匹配模式,至多出现一次。以下列出一些重复的标示:
- * :星号,重复任意多次,如:\w*,代表任意字母,数字,下划线,汉字出现任意多次
- + :加号:至少出现一次,如:\d+,代表任意数字至少出现一次
- ? :问好:至多出现一次(出现一次或则不出现),如:\s?,代表空白字符出现0或则1次
- {n}:n代表任意数字,如:.{5},代表任意字符出现5次
- {n,}:n代表任意数字,如:\d{5,},代表任意数字出现5到多次
- {n,m}:n,m代表任意数字,如:\d{5,10},代表任意数字出现5到10次
1)re.match("[A-Z][a-z]*","Liujianhong ")
re.match("[A-Za-z]*","LiuJianhong ")
re.match("[A-Z][a-z]*","LiuJianhong ")
2)re.match("[a-zA-Z_]+[\w_]*","LiuJianhong3 ")
3)re.match("[0-9]?[\d]","1")
re.match("[0-9]?[\d]","111")
4)re.match("\w{5}","1sadfasdf11")
5)re.match("\w{5,}","1sadfasdf11")
6)re.match("\w{5,9}","1sadfasdf11")
re.match(".*\\bliu\\b","i is liu fas fsa5 662 2a") # 注意为什么使用点
re.match(r".*\bliu\b","i is liu fas fsa5 662 2a") #结果同上
贪婪与惰性匹配
首先看一个正则表达式例子:“<.>”
这个正则表达式将匹配以’<’开头,’>’结尾中间任意次任意字符,
如:
,,等。
当如果用该正则表达式去匹配hello world的话被匹配出的文本就是hello world,因为默认情况下正则表达式是贪婪匹配。正则表达式引擎或默认情况下将默认搜索最后一个匹配锚点。所以本例中的最后匹配锚点是