介绍
正则表达式(Regular expressions)有两个用处:
- 辨别字符是否匹配一个pattern
- 对字符进行处理
在Python中通过re模块引用正则表达式。
当你定义了一个正则表达式,可以用re.match功能辨别字符是否匹配。
为了避免字符上的混淆,我们可以用r"expression"来表示字符串。
例如:
import re
pattern = r"spam"
if re.match(pattern,"spamspamspam"): //检查是否以spam开头
print("Match")
else:
print("No match")
>>>
Match
>>>
另外一个匹配功能是re.search和re.findall.
re.search在一组字符串的任意位置找到匹配项。
re.findall将所有匹配字符返回到一个列表。
例如:
import re
parttern = r"spam"
if re.match(pattern,"eggspamsausagespam"):
print("Match")
else:
print("No match")
if re.search(pattern,"eggspamsausagespam"):
print("Match")
else:
print("No match")
print(re.findall(pattern, "eggspamsausagespam"))
结果:
>>>
No match
Match
['spam', 'spam']
>>>
正则搜索有以下几种methods:
- group 返回匹配的字符
- start 返回匹配字符开始的位置
- end 返回匹配字符结束的位置
- span 返回一个元组:(开始位置,结束位置)
例如:
import re
pattern = r"pam"
match = re.search(pattern, "eggspamsausage")
if match:
print(match.group())
print(match.start())
print(match.end())
print(match.span())
结果:
>>>
pam
4
7
(4, 7)
>>>
另外在re模块中还有个特别重要的正则式:sub。
语法规则:
re.sub(pattern, repl, string, max=0)
这个方法将在string处查找pattern中的字符,然后替换为repl的字符,最后返回修改后的语句。
例如:
import re
str = "My name is David. Hi David."
pattern = r"David"
newstr = re.sub(pattern, "Amy", str)
print(newstr)
结果:
>>>
My name is Amy. Hi Amy.
>>>
简单的元字符
元字符使得正则表达式比一般字符方法更加强大。
第一个元字符是.(原点)。
他的作用是匹配任何一个单字字符(除了换行符号)。
例如:
import re
pattern = r"gr.y"
if re.match(pattern, "grey"):
print("Match 1")
if re.match(pattern, "gray"):
print("Match 2")
if re.match(pattern, "blue"):
print("Match 3")
>>>
Match 1
Match 2
>>>
接下来两个元字符是^和$,作用分别是匹配一个字符的开始和结束。
例如:
import re
pattern = r"^gr.y$" //匹配以gr开头,以y结尾,中间只有一个字符的字符串。
if re.match(pattern, "grey"):
print("Match 1")
if re.match(pattern, "gray"):
print("Match 2")
if re.match(pattern, "stingray"):
print("Match 3")
>>>
Match 1
Match 2
>>>
字符类
字符类提供了一个匹配一组特定字符中唯一字符的方法。
用中括号来创建一组字符类。
例如
import re
pattern = r"[aeiou]" //匹配[aeiou]中任意字符
if re.search(pattern, "grey"):
print("Match 1")
if re.search(pattern, "qwertyuiop"):
print("Match 2")
if re.search(pattern, "rhythm myths"):
print("Match 3")
>>>
Match 1
Match 2
>>>
字符类也能匹配字符域,比如:
[a-z]匹配所有小写字符。
[G-P]匹配所有大写字符。
[0-9]匹配所有数字。
多个域可以合到一个类里。比如[A-Za-z]可以匹配26个字母中任意一个。
import re
pattern = r"[A-Z][A-Z][0-9]"
if re.search(pattern, "LS8"):
print("Match 1")
if re.search(pattern, "E3"):
print("Match 2")
if re.search(pattern, "1ab"):
print("Match 3")
>>>
Match 1
>>>
^放置于字符类的开头,用于反置,即匹配除字符类之外的字符。
import re
pattern = r"[^A-Z]" //匹配除大写字母外的字符。注意,^要放在括号里面!!!
if re.search(pattern, "this is all quiet"):
print("Match 1")
if re.search(pattern, "AbCdEfG123"):
print("Match 2")
if re.search(pattern, "THISISALLSHOUTING"):
print("Match 3")
>>>
Match 1
Match 2
>>>
更多的元字符
更多的元字符包括:
***** 表示0或更多次重复。
例如:
import re
pattern = r"egg(spam)*"
if re.match(pattern, "egg"):
print("Match 1")
if re.match(pattern, "eggspamspamegg"):
print("Match 2")
if re.match(pattern, "spam"): //没有以egg开头
print("Match 3")
>>>
Match 1
Match 2
>>>
+ 类似于*,表示1或更多次重复。
例如:
import re
pattern = r"g+"
if re.match(pattern, "g"):
print("Match 1")
if re.match(pattern, "gggggggggggggg"):
print("Match 2")
if re.match(pattern, "abc"):
print("Match 3")
>>>
Match 1
Match 2
>>>
? 表示重复1或0次。
例如:
import re
pattern = r"ice(-)?cream"
if re.match(pattern, "ice-cream"):
print("Match 1")
if re.match(pattern, "icecream"):
print("Match 2")
if re.match(pattern, "sausages"):
print("Match 3")
if re.match(pattern, "ice--ice"):
print("Match 4")
>>>
Match 1
Match 2
>>>
花括号{x,y} 用来代表重复次数,x和y表示重复次数的范围。所以{0,1}就等于?。如果y不填,默认为无穷大。
例如:
import re
pattern = r"9{1,3}$"
if re.match(pattern, "9"):
print("Match 1")
if re.match(pattern, "999"):
print("Match 2")
if re.match(pattern, "9999"): //重复了4次。超出了范围。
print("Match 3")
>>>
Match 1
Match 2
>>>
组
用一对括号()可以创建一个组,组可以添加元字符,比如*和?。
例如:
import re
pattern = r"egg(spam)*"
if re.match(pattern, "egg"):
print("Match 1")
if re.match(pattern, "eggspamspamspamegg"):
print("Match 2")
if re.match(pattern, "spam"):
print("Match 3")
>>>
Match 1
Match 2
>>>
组中的内容可以通过group功能访问。
调用group(0)和group()可以返回整个匹配内容。
调用group(n),n要大于0,可以返回从左数第n个组。
groups()方法返回所有组。
例如:
import re
pattern = r"a(bc)(de)(f(g)h)i"
match = re.match(pattern, "abcdefghijklmnop")
if match:
print(match.group())
print(match.group(0))
print(match.group(1))
print(match.group(2))
print(match.groups())
>>>
abcdefghi
abcdefghi
bc
de
('bc', 'de', 'fgh', 'g')
>>>
特殊事项
import re
pattern = r"(.+)\1"
match = re.match(pattern,"word word")
if match:
print("Match 1")
match = re.match(pattern,"?! ?!")
if match:
print("Match 2")
match = re.match(pattern,"abc cde")
if match:
print("Match 3")
Result:
>>>
Match 1
Match 2
>>>
Email检查
为了举例演示正则表达式的用法,我们来创建一个检查邮件地址字符的小程序。
假设我们已经有一段包含邮件地址的文字了:
str = "Please contact info@sololearn.com for assistance"
我们的目标是提取这段文字 "info@sololearn.com"。
基本的邮件地址会包含一串文字或者可能还有点号和划线,后头跟着个@符号,再后头是域名。
这里是建立我们正则式的基础知识。
pattern = r"([\w\.-]+)@([\w\.-]+)(\.[\w\.]+)"
[\w.-]+ 匹配一个或者更多单词、点号或者划线,然后跟着一个@,再接着是个.,然后又是一个单词。
然后把这些合起来:
import re
pattern = r"([\w\.-]+)@([\w\.-]+)(\.[\w\.]+)"
str = "Please contact info@sololearn.com for assistance"
match = re.search(pattern, str)
if match:
print(match.group())
>>>
info@sololearn.com
>>>
网友评论