1.1 正则表达式符号表
1.1.1 符号
表示法 | 描述 | 正则表达式示例 |
---|
literal | 匹配文本字符串的字面值 | foo |
re1|re2 | 匹配正则表达式re1\re2 | foo |
. | 陪陪任何字符(除了\n之外) | b.b |
^ | 匹配字符串起始部分 | ^Dear |
$ | 匹配字符串终止部分 | /bin/*sh$ |
* | 匹配0次或者多次前面出现的正则表达式 | [A-Za-z0-9]* |
+ | 匹配1次或者多次前面出现的正则表达式 | [a-z]+\.com |
? | 匹配0次或者1次前面出现的正则表达式 | goo? |
{N} | 匹配N次前面出现的正则表达式 | [0-9]{3} |
{M,N} | 匹配M~N次前面出现的正则表达式 | [0-9]{5,9} |
[…] | 匹配来自字符集的任意单一字符 | [aeiou] |
[..x-y..] | 匹配x~y范围中的任意单一字符 | [0-9],[A-Za-z] |
[^…] | 不匹配次字符集中出现的任何一个字符,包括某一范围的字符(如果再次字符集中出现) | [^aeiou],[^A-Za-z0-9] |
(*|+|?|{})? | 用于匹配上面频繁出现/重复出现符号的非贪婪版本(*、+、?、{}) | .*?[a-z] |
(…) | 匹配封闭的正则表达式,然后另存为子组 | ([0-9]{3})?,f(oo |
1.1.2 特殊字符
表示法 | 描述 | 正则表达式示例 |
---|
\d | 匹配任何十进制数字,与[0-9]一致(\D与\d相反) | data\d+.txt |
\w | 匹配任何字母数字字符,与[A-Za-z0-9]相同(\W与之相反) | [A-Za-z_]\w+ |
\s | 匹配任何空格字符,与[\n\t\r\v\f]相同(\S与之相反) | of\sthe |
\b | 匹配任何单词边界(\B与之相反) | \bThe\b |
\N | 匹配已保存的子组N(参见上面的(…)) | price:\16 |
\c | 逐字匹配任何特殊字符c(不匹配特殊含义) | .\,* |
\A(\Z) | 匹配字符串的起始(结束)(另见上面的^和$) | \ADear |
1.1.3扩展表示法
表示法 | 描述 | 正则表达式示例 |
---|
(?iLmsux) | 在正则表达式中嵌入一个或多个特殊的“标记”参数(或者通过函数/方法) | (?x),(?im) |
(?:…) | 表示一个匹配不用保存的分组 | (?:\w+.)* |
(?P< name>…) | 像一个仅由name标识而不是数字ID标识的正则分组匹配 | (?P< data>) |
(?P=name…) | 在同一个字符串中匹配由(P? | (?P=data) |
(?#…) | 表示注释所有内容都被忽略 | (?#comment) |
(?=…) | 匹配条件是如果…出现在之后的位置,而不使用输入字符串;称作正向前视断言 | (?=.com) |
(?!…) | 匹配条件是如果…不出现在之后的位置,而不使用输入字符串;称作负向前视断言 | ?!.net |
(?<=…) | 匹配条件是如果…出现在之前的位置,而不使用输入字符串;称作正向后视断言 | ?<=800- |
(?<!…) | 匹配条件是如果…不出现在之前的位置,而不使用输入字符串;称作负向后视断言 | (?<!192\.168\.) |
(?(id(name)Y|N) | 如果分组所一共的id或者name(名称存在),就返回正则表达式的条件匹配Y,如果不存在,就返回N;|N是可选项 | (?(l)y|x) |
1.2 Python中的正则
Python通过标准库中的re模式支持正则表达式
1.2.1 re模块函数
函数/方法 | 描述 |
---|
compile(pattern,flags=0) | 使用任何可选的标记来编译正则表达式的模式,然后返回一个正则表达式的对象 |
1.2.2 re模块函数和正则表达式对象方法
函数/方法 | 描述 |
---|
match(pattern,string ,flags=0) | 尝试使用带有可选标记的正则表达式的模式来匹配字符串。如果匹配成功就返回匹配对象;如果失败,就返回None |
search(pattern,string,flags=0) | 使用可选标记搜索字符串中第一次出现的正则表达式模式。如果匹配成功就返回匹配对象;如果失败,就返回None |
findall(pattern,string[,flags]) | 查找字符串中所有(非重复)出现的正则表达式模式,病返回一个匹配列表 |
finditer(pattern,string[,flags]) | 与findall函数相同,但返回的不是一个列表,而是一个迭代器。对于每一次匹配,迭代器都返回一个对象 |
split(pattern,string,max=0) | 根据正则表达式的模式分隔符,split函数将字符串分割为列表,然后返回成功匹配的列表,分隔最多操作max次(默认分隔所有匹配成功的位置) |
sub(pattern,repl,string,count=0) | 使用repl替换所有正则表达式的模式在字符串中出现的位置,除非定义count,否则就将替换所有出现的位置 |
purge() | 清除隐式编译的正则表达式模式 |
1.2.3 常用的匹配对象方法(查看文档以获取更多信息)
函数/方法 | 描述 |
---|
group(num=0) | 返回整个匹配对象,或者编号为num的特定子组 |
groups(default=None) | 返回包含所有匹配子组的元组(如果没有匹配成功就返回一个空元组) |
groupdict(default=None) | 返回一个包含所有匹配的命名子组的字典,所有的子组名称作为字典的键(如果没有成功匹配,就返回一个空字典) |
1.2.4 常用模块属性(用于大多数正则表达式函数的标记)
函数/方法 | 描述 |
---|
re.I、re.IGORECASE | 不区分大小写的匹配 |
re.L、re.LOCALE | 根据所使用的本地语言环境通过\w、\W、\b、\B、\s、\S实现匹配 |
re.M、re.MULTILINE | ^和$分别匹配目标字符串中行的起始和结尾,而不是严格匹配整个字符串本身的起始和结尾 |
re.S、re.DOTALL | “.”通常匹配除了\n以外的所有单字符;该标记表示”.” |
re.X、re.VERBOSE | 通过反斜线转义,否则所有空格加上#(以及在该行中所有后续文字)都被忽略,除非在一个字符勒种或者允许注释并且提高可读性 |
1.2.5 一些示例
1.2.5.1 match()方法
>>> import re
>>> m=re.match('foo','foo')
>>> if m is not None:
m.group()
结果:
'foo'
1.2.5.2 search()方法
>>> import re
>>> m=re.search('foo','seafood')
>>> if m is not None:m.group()
结果:
'foo'
1.2.5.3 重复特殊字符以及分组
1)
>>> import re
>>> patt='\w+@(\w+\.)*\w+\.com'
>>> re.match(patt,'nobody@www.xxx.yyy.zzz.com').group()
'nobody@www.xxx.yyy.zzz.com'
2)
>>> import re
>>> m=re.match('(\w\w\w)-(\d\d\d)','abc-123')
>>> m.group()
'abc-123'
>>> m.group(1)
'abc'
>>> m.group(2)
'123'
>>> m.groups()
('abc', '123')
1.2.5.4 使用findall()和finditer()
>>> s='This and that.'
>>> re.findall(r'(th\w+) and (th\w+)',s,re.I)
[('This', 'that')]
>>> re.findall('(th\w+) and (th\w+)',s,re.I)
[('This', 'that')]
>>> re.findall(r'((th\w+) and (th\w+))',s,re.I)
[('This and that', 'This', 'that')]
>>> it=next(re.finditer(r'(th\w+) and (th\w+)',s,re.I))
>>> it.group(1)
'This'
1.2.5.5 使用sub()和subn()
>>> import re
>>> re.sub('[ae]','X','abcdef')
'XbcdXf'
>>> re.subn('[ae]','X','abcdef')
('XbcdXf', 2)
1.2.5.6 使用split()
DATA=(
'Mountain View, CA 94040',
'Sunnyvale, CA',
'Los Altos, 94023',
'Cupertino 95014',
'Palo Alto CA',
)
for datum in DATA:
print(re.split(', |(?= (?:\d{5}|[A-Z]{2})) ',datum))
结果:
['Mountain View', 'CA', '94040']
['Sunnyvale', 'CA']
['Los Altos', '94023']
['Cupertino', '95014']
['Palo Alto', 'CA']
1.2.5.7 扩展符号的使用
>>> re.findall(r'(?i)yes','yes?Yes. YES!!')
['yes', 'Yes', 'YES']
>>> re.findall(r'(?im)(^th[\w ]+)',"""
This line is the first,
another line,
that line, it's the best
""")
['This line is the first', 'that line']
>>> re.findall(r'(?s)th.+','''
the first line
the second line
the third line
''')
['the first line\nthe second line\nthe third line\n']
>>> re.search(r'''(?x)
\((\d{3})\) #区号
[ ] #空白符
(\d{3}) #前缀
- #横线
(\d{4}) #终点数字
''','(800) 555-1212').groups()
('800', '555', '1212')
>>> re.findall(r'http://(?:\w+\.)*(\w+\.com)',
'http://google.com http://www.google.com http://code.google.com')
['google.com', 'google.com', 'google.com']
>>> re.findall(r'(?:\w+\.)*(\w+\.com)',
'http://google.com http://www.google.com http://code.google.com')
['google.com', 'google.com', 'google.com']
>>> re.search(r'\((?P<areacode>\d{3})\) (?P<prefix>\d{3})-(?:\d{4})','(800) 555-1212').groupdict()
{'areacode': '800', 'prefix': '555'}
>>> re.sub(r'\((?P<areacode>\d{3})\) (?P<prefix>\d{3})-(?:\d{4})','(\g<areacode>) \g<prefix>-xxxx','(800) 555-1212')
'(800) 555-xxxx'
>>> re.match(r'\((?P<areacode>\d{3})\) (?P<prefix>\d{3})-(?P<number>\d{4}) (?P=areacode)-(?P=prefix)-(?P=number) 1(?P=areacode)(?P=prefix)(?P=number)','(800) 555-1212 800-555-1212 18005551212')
结果:
<_sre.SRE_Match object; span=(0, 39), match='(800) 555-1212 800-555-1212 18005551212'>
>>>re.findall(r'(?m)^\s+(?!noreply|postmaster)(\w+)','''
sales@phptr.com
postmaster@phptr.com
eng@phptr.com
noreply@phptr.com
admin@phptr.com
''')
['sales', 'eng', 'admin']
bool(re.search(r'(?:(x)|y)(?(1)y|x)','xy'))
True
>>> bool (re.search(r'(?:(x)|y)(?(1)y|x)','xx'))
False