第一章 正则表达式

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,'[email protected]').group()
'[email protected]'

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 扩展符号的使用

#Python的正则支持大量的扩展符号

#re.I/IGNORECASE
>>> re.findall(r'(?i)yes','yes?Yes. YES!!')
['yes', 'Yes', 'YES']

#re.M/MULTILINE
>>> 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.S/DOTALL
>>> 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.X/VERBOSE
>>> 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']

#(?P<name>)
>>> re.search(r'\((?P<areacode>\d{3})\) (?P<prefix>\d{3})-(?:\d{4})','(800) 555-1212').groupdict()
{'areacode': '800', 'prefix': '555'}

#\g<name>
>>> re.sub(r'\((?P<areacode>\d{3})\) (?P<prefix>\d{3})-(?:\d{4})','(\g<areacode>) \g<prefix>-xxxx','(800) 555-1212')
'(800) 555-xxxx'

#(?P=name)
>>> 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+)','''
    [email protected]
    [email protected]
    [email protected]
    [email protected]
    [email protected]
''')
['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

猜你喜欢

转载自blog.csdn.net/u012889441/article/details/70991161