正则表达式:regular expression,缩写是regex。
本章最后会有让你自动摘取文本中的电话号码和邮箱地址。
1.用正则表达式来寻找合适的电话号码:
三个发展阶段
用def定义函数—\d\d\d-\d\d\d\d-\d\d\d—\d{3}-\d{4}-\d{3}
其中\d代表数字0-9,就不需要再使用def再去筛选是否是数字了。
{ }在此表示,匹配之前的模式相对应的次数。
2.所有python中的regex在re中,所以要先import re
正则表达式
phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')
#这里的compile是什么意思?此句代表建立一个正则表达式。
mo = phoneNumRegex.search('My number is 415-555-4242.')
#这里的search指要搜索的对象,如果搜索不到对象则会返回none。
print('Phone number found: ' + mo.group())
#这里的group指对答案的集合???他明明不是集合为什么要用group
正则表达式的更多模式匹配
group模式
例如要将电话里的前半部分和后半部门分开来找,在此group(1)代表第一个(里的部分),group(0)和group()一样,都代表输出整个。groups()代表分别输出()里的内容并且按照格式。
phoneNumRegex = re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)')
mo = phoneNumRegex.search('My number is 415-555-4242.')
mo.group(1)
'415'
mo.group(2)
'555-4242'
mo.group(0)
'415-555-4242'
mo.group()
'415-555-4242'
mo.groups()
('415', '555-4242')
areaCode, mainNumber = mo.groups()
print(areaCode)
415
print(mainNumber)
555-4242
PIPE管道模式
匹配多个正则表达式的时候可以用|连接,匹配到的第一个合适的内容会被输出,之后的就不会有输出了。
正则表达式如何输出多个结果?使用findall
用问号标记随机匹配的正则表达式
问号前的东西可以有也可以没有。
batRegex = re.compile(r'Bat(wo)?man')
mo1 = batRegex.search('The Adventures of Batman')
mo1.group()
'Batman'
mo2 = batRegex.search('The Adventures of Batwoman')
mo2.group()
'Batwoman'
用*匹配0或更多该内容的正则表达式
batRegex = re.compile(r'Bat(wo)*man')
mo1 = batRegex.search('The Adventures of Batman')
mo1.group()
'Batman'
mo2 = batRegex.search('The Adventures of Batwoman')
mo2.group()
'Batwoman'
mo3 = batRegex.search('The Adventures of Batwowowowoman')
mo3.group()
用+匹配1个或以上的标记内容的正则表达式
batRegex = re.compile(r'Bat(wo)+man')
mo1 = batRegex.search('The Adventures of Batwoman')
mo1.group()
'Batwoman'
mo2 = batRegex.search('The Adventures of Batwowowowoman')
mo2.group()
'Batwowowowoman'
mo3 = batRegex.search('The Adventures of Batman')
mo3 == None
True
用{ }匹配的特定重复的内容
比如匹配(ha){3},就是指匹配hahaha;
比如(ha){3,5},就是匹配3-5个ha
比如(ha){3,}匹配3个以及无限多的ha
但有个问题,在使用{3,5}时,匹配的结果总是出现5个ha的那个,这是因为系统的greedy,如果要让系统non-greedy(在此的意思就是输出的是3个ha的那种),需要变成另外一种格式,就是在{ }加上?。
注意,这边的?和(ha)?中的这个意义是不同的。
findall
- 在使用re.compile search时,出现的结果都只有一个匹配项,如果想让所有匹配项都出现,需要用到findall。
- 使用的时候不能再用group了,因为findall结果将会以列表的形势出现。
- 要陈列匹配结果的时候,需要将原来的search改成findall。
- 如果用findall,正则表达式中那个匹配公式是没有group的。
正则表达式中的代表字符缩写和其意义
Shorthand character class | Represents |
---|---|
\d | Any numeric digit from 0 to 9. |
\D | Any character that is not a numeric digit from 0 to 9. |
\w | Any letter, numeric digit, or the underscore character. (Think of this as matching “word” characters.) |
\W | Any character that is not a letter, numeric digit, or the underscore character. |
\s | Any space, tab, or newline character. (Think of this as matching “space” characters.) |
\S | Any character that is not a space, tab, or newline. |
我们也可以自己做正则表达式的搜索范围,用[ ]中的内容表示
比如[a-z]代表所有的小写字母。如果将放在a的前面[a-z],代表是后面的反义词,代表只匹配除了[]里的其他内容。
限定开始和结束
如果将^ 放在字符串的前面,代表以xxxx开头的意思,比如r’^[a-z]’或者 r’^hello’。
如果是$放在字符串结尾,代表以什么为结束。
如果一个字符串里既有^又有$,代表整个字符串都必须是什么。
通配符
通配符“.”,这个代表可以匹配除换行以外的所有字符,但是只能匹配一个字符。
如果想匹配多一些的字符,可以使用“.*”,但也不包括匹配换行的。
如果想匹配换行的,可以调用re里的dotall。
noNewlineRegex = re.compile('.*')
noNewlineRegex.search('Serve the public trust.\nProtect the innocent.
\nUphold the law.').group()
'Serve the public trust.'
newlineRegex = re.compile('.*', re.DOTALL)
newlineRegex.search('Serve the public trust.\nProtect the innocent.
\nUphold the law.').group()
'Serve the public trust.\nProtect the innocent.\nUphold the law.'
符号复习Review of Regex Symbols
This chapter covered a lot of notation, so here’s a quick review of what you learned:
The ? matches zero or one of the preceding group.
The * matches zero or more of the preceding group.
The + matches one or more of the preceding group.
The {n} matches exactly n of the preceding group.
The {n,} matches n or more of the preceding group.
The {,m} matches 0 to m of the preceding group.
The {n,m} matches at least n and at most m of the preceding group.
{n,m}? or *? or +? performs a nongreedy match of the preceding group.
^spam means the string must begin with spam.
spam$ means the string must end with spam.
The . matches any character, except newline characters.
\d, \w, and \s match a digit, word, or space character, respectively.
\D, \W, and \S match anything except a digit, word, or space character, respectively.
[abc] matches any character between the brackets (such as a, b, or c).
[^abc] matches any character that isn’t between the brackets.
想要忽略大小写的匹配正则表达式
使用re.IGNORECASE或者使用re.I,作为re.compile()内部的第二个参数。
练习项目中为什么要加上r?
三个引号是什么意思?
pyperclip的用法?
为什么findall后面就不能用group(),只有search后面能跟group。