第一章 正则表达式

1.1 正则表达式符号表

1.1.1 符号

表示法描述正则表达式示例
literal匹配文本字符串的字面值foo
re1|re2匹配正则表达式re1\re2foo
.陪陪任何字符(除了\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 扩展符号的使用
#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+)','''
    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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值