Python正则表达式指南这篇文章很好,推荐阅读。
本文则是简单记录下我本身学习Re的笔记, 环境是python3.5。html
^
匹配字符串开始位置。$
匹配字符串结束位置。\b
匹配一个单词边界。\d
匹配一个数字。\D
匹配一个任意的非数字字符。x?
匹配可选的 x 字符。换句话说,就是 0 个或者 1 个 x 字符。可是?还有第二个含义,做为正则的懒惰模式。x*
匹配 0 个或更多的 x。x+
匹配 1 个或者更多 x。x{n,m}
匹配 n 到 m 个 x,至少 n 个,不能超过 m 个。x{n}
匹配n个x,必定是n个(a|b|c)
匹配单独的任意一个 a 或者 b 或者 c。(x)
这是一个组,它会记忆它匹配到的字符串。\w
一个字母或数字.
任意字符\s
空格[]
表示范围,[0-9a-zA-Z_]能够匹配一个数字、字母或者下划线。[^]
做为方括号中的第一个字符, ^
有特别的含义:非。 [^abc]
的意思是: “ 除了 a、 b 或 c以外的任何字符”。>>> re.search('[^aeiou]y$', 'vacancy') <_sre.SRE_Match object; span=(5, 7), match='cy'> >>> re.search('[^aeiou]y$', 'boy') >>>
若是你想要指示某些不须要如转义符那样的特别处理的字符串,那么你须要指定一个天然字符串。天然字符串经过给字符串加上前缀r或R来指定。例如r"Newlines are indicatedby \n"。
必定要用天然字符串处理正则表达式。不然会须要使用不少的反斜杠。例如,后向引用符能够写成'\1'或r'\1'。
强烈建议使用 Python 的 r 前缀,就不用考虑转义的问题了。python
search()
的帮助信息:Scan through string looking for a match to the pattern, returning a match object, or None if no match was found.
。match()
的帮助信息:Try to apply the pattern at the start of the string, returning a match object, or None if no match was found.
。正则表达式
re 模块最基本的方法是 search()
函数(相似于match()函数)。它使用正则表达式来匹配字符串( M)。若是成功匹配, search()返回一个匹配对象。shell
>>> pattern = '^M?M?M?$' >>> re.search(pattern, 'M') <_sre.SRE_Match object; span=(0, 1), match='M'>
match()函数一样的功能。express
>>> pattern = '^M?M?M?$' >>> re.match(pattern, 'M') <_sre.SRE_Match object; span=(0, 1), match='M'>
re.match()
只匹配字符串的开始,若是字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search()
匹配整个字符串,直到找到一个匹配。app
#!/usr/bin/python import re line = "Cats are smarter than dogs"; matchObj = re.match( r'dogs', line, re.M|re.I) if matchObj: print("match --> matchObj.group() : ", matchObj.group()) else: print("No match!!") matchObj = re.search( r'dogs', line, re.M|re.I) if matchObj: print("search --> matchObj.group() : ", matchObj.group()) else: print("No match!!") # No match!! # search --> matchObj.group() : dogs # [Finished in 0.1s]
Compile a regular expression pattern, returning a pattern object.
Re模块的compile()
方法编译正则表达式,返回一个pattern对象。
编译后生成的 pattern 对象,已经包含了正则表达式(regular expression),因此调用对应的方法时不用给出正则表达式了。
用编译后的pattern对象去匹配字符串patternobj.search(string)
,若是匹配成功,返回的结果调用groups()
方法,能够获得这个正则表达式中定义的全部分组结果组成的元组。
但若是search()
方法匹配不成功,返回None
,它没有 groups()
方法,因此调用 None.groups()将会抛出一个异常。ssh
>>> phonePattern = re.compile(r'^(\d{3})-(\d{3})-(\d{4})$') >>> dir(phonePattern) ['__class__', '__copy__', '__deepcopy__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'findall', 'finditer', 'flags', 'fullmatch', 'groupindex', 'groups', 'match', 'pattern', 'scanner', 'search', 'split', 'sub', 'subn'] >>> phonePattern re.compile('^(\\d{3})-(\\d{3})-(\\d{4})$') >>> m = phonePattern.search('800-555-1212') >>> m <_sre.SRE_Match object; span=(0, 12), match='800-555-1212'> >>> m.groups() ('800', '555', '1212') # 匹配失败 >>> phonePattern.search('800-555-1212-1234').groups() Traceback (most recent call last): File "<pyshell#24>", line 1, in <module> phonePattern.search('800-555-1212-1234').groups() AttributeError: 'NoneType' object has no attribute 'groups'
Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement repl. repl can be either a string or a callable; if a string, backslash escapes in it are processed. If it is a callable, it's passed the match object and must return a replacement string to be used.
正则表达式模块的re.sub()
函数能够作字符串替换,以下它在字符串 s 中用正则表达式‘ROAD$’来搜索并替换成‘RD.’。函数
>>> s = '100 NORTH BROAD ROAD' >>> import re >>> re.sub('ROAD$', 'RD.', s) '100 NORTH BROAD RD.'
>>> re.sub('[abc]', 'o', 'caps') 'oops'
可能会认为该函数会将 caps 转换为 oaps,但实际上并非这样。re.sub()
替换全部的匹配项,而不只仅是第一个匹配项。所以该正则表达式将 caps 转换为 oops,由于不管是 c 仍是 a 均被转换为 o 。
在替换字符串中,用到了新的语法: \1,它表示“嘿,记住的第一个分组呢?把它放到这里。 ”在此例中, 记住了 y 以前的 c ,在进行替换时,将用 c 替代 c,用 ies 替代 y 。(若是有超过一个的记忆分组,可使用 \2 和 \3 等等。)oop
>>> re.sub('([^aeiou])y$', r'\1ies', 'vacancy') 'vacancies'
Return a list of all non-overlapping matches in the string. If one or more capturing groups are present in the pattern, return a list of groups; this will be a list of tuples if the pattern has more than one group. Empty matches are included in the result.
re.findall()
接受一个正则表达式和一个字符串做为参数,而后找出字符串中出现该模式的全部地方。在这个例子里,模式匹配的是数字序列。findall()
函数返回全部匹配该模式的子字符串的列表。学习
>>> re.findall('[0-9]+', '16 2-by-4s in rows of 8') ['16', '2', '4', '8']
这里正则表达式匹配的是字母序列。再一次,返回值是一个列表,其中的每个元素是匹配该正则表达式的字符串。
>>> re.findall('[A-Z]+', 'SEND + MORE == MONEY') ['SEND', 'MORE', 'MONEY']
懒惰模式和贪婪模式
.*
具备贪婪的性质,首先匹配到不能匹配为止,根据后面的正则表达式,会进行回溯。
.*?
则相反,一个匹配之后,就往下进行,因此不会进行回溯,具备最小匹配的性质。
?
的一个用法是匹配0次或1次。可是?
还有第二个含义,做为正则的懒惰模式。后边多一个?
表示懒惰模式,必须跟在*
或者+
后边用。
re 正则有两种模式,一种为贪婪模式(默认),另一种为懒惰模式,如下为例:
(abc)dfe(gh)
对上面这个字符串使用(.*)
将会匹配整个字符串,由于正则默认是尽量多的匹配。
虽然(abc)
知足咱们的表达式,可是(abc)dfe(gh)
也一样知足,因此正则会匹配多的那个。
若是咱们只想匹配(abc)
和(gh)
就须要用到如下的表达式(.*?)
惰性模式匹配示例:
>>> re.findall(' s.*? s', "The sixth sick sheikh's sixth sheep's sick.") [' sixth s', " sheikh's s", " sheep's s"] >>> re.findall(' s.* s', "The sixth sick sheikh's sixth sheep's sick.") [" sixth sick sheikh's sixth sheep's s"]
加上分组:
>>> re.findall(' s(.*?) s', "The sixth sick sheikh's sixth sheep's sick.") ['ixth', "heikh's", "heep's"]