第一章 正则表达式

来源:互联网 发布:c 定义二维数组 编辑:程序博客网 时间:2024/05/29 19:10

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

#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 linethe second linethe 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