Python学习之路(33)——正则表达式re模块
re模块提供与Perl中类似的正则表达式匹配操作。
其中,被搜索的模式和字符串都可以是Unicode字符串以及8-bit字符串。但是,在匹配时,Unicode字符串和8-bit字符串不能混用在一起(因为,不能使用字节模式去匹配字Unicode字符串,反之亦然。);相似的,当准备做替换操作时,替换的字符串或模式也一定要和被替换的字符串或模式一致。
正则表达式使用反斜杠字符'\'表示特殊形式或允许使用特殊字符,而不调用期特殊意义。这与Python在字符串文字中用于相同目的的相同字符的使用相冲突:例如为了匹配字面值的反斜杠,必须以'\\\\'作为模式字符串,因为正则表达式必须是\\,每个反斜杠必须在常规Python字符串字面值内表示为\\。
现在可以用Python原始字符串符号的正则表达式模式来解决上面的繁琐处理方式:不以任何特殊方式在字符串字面值中以'r'前缀处理反斜杠。比如r"\n"表示'\'和'n'两个字符。所以通常在Python代码中,使用原始字符串表示模式。
一、正则表达式语法
正则表达式(或RE)指定一组字符串匹配它。
正则表达式可以包含特殊或普通字符。比如'A','a','0',是最简单的正则表达式(只与自己本身相匹配);某些字符是含有特殊意义的,要么表示一个类别的普通字符,要么影响它们周伟的正则表达式如何解释。
以下介绍一些最常用到的:
1、特殊字符:
'.':(点号)在默认模式下,匹配除换行符外的任何字符。当re.DOTALL标记被指定时,则可以匹配包括换行符的任何字符。
'^':(脱字符号)从字符串的开始匹配,在MULTILINE模式下每个换行符后面立即开始匹配。
'$':匹配字符串的结果或只是之前换行符结尾的字符串,并在MULTILINE模式下也匹配在换行符之前。(比如,foo匹配'foo'和'foobar',而foo$仅匹配'foo';正常情况下foo.$在'foo1\nfoo2\n'中只匹配foo2,但在MULTILINE模式下foo1也能匹配到;单独使用$在'foo\n'中可以得到2个空的匹配,一个在新行之前,一个在字符串foo之后)
'*':匹配前面重复出现的正则表达式0次或多次。(ab*可以匹配a,ab,abbbbbbb...)
'+':匹配前面重复出现的正则表达式1次或多次。(ab+可以匹配ab,abbbbbb....,但不能匹配a)
'?':匹配前面重复出现的正则表达式0次或1次。(ab?将只能匹配a,ab)
*?,+?,??:'*','+','?'都是贪婪模式(尽可能多的匹配)。如果不希望匹配多次,可以加上?限定符使得匹配为非贪婪模式或者最小匹配,尽可能少的字符被匹配。
{m}:精确指定RE应该匹配m次,少于m次将导致RE不会被匹配上。
{m,n}:匹配前面重复出现的正则表达式m到n次,尽可能多的匹配。可以单独省略m或n,表示无下限和无上限,但是逗号不可以省略。
{m,n}?:匹配前面重复出现的正则表达式m到n次,尽可能少的匹配。(比如6个字符的字符串'aaaaaa',a{3,5}匹配得到5个'a'的字符串'aaaaa',而a{3,5}?只能匹配到3个'a'的字符'aaa')
'\':消除特殊字符含义(允许匹配'*'、'?'这样的特殊字符)
[]:表示一个字符集合。这里集合里:
- 字符可以单独罗列([amk]会匹配'a'、'm'、'k')
 - 字符范围可以通过两个字符和它们之间的'-'表明([z]将匹配任何小写字母的ASCII字母,[0-5][0-9]强匹配00-59;如果分隔符'-'被反斜杠转义,或者放在[]内的第一个或最后一个字符,则只作为'-'匹配)
 - 在[]集合内的特殊字符失去意义([(+*?)]将匹配'('、'+','*','?'或')')
 - 补集:[]集合内的第一个字符是'^'的话,那么所有不在集合内的将被匹配上([^5]将匹配除5一位的任意字符,而如果'^'不在集合内是第一个字符的话,仅匹配自己,没有特殊意义)
 - 想要在一个集合内匹配']',需要在它前面使用一个反斜杠进行转义,或者在其作为集合内开头的字符(比如[()[\]{}]和[]()[{}]将匹配括号字符
 
'|':RE1|RE2,将匹配A或B的正则表达式。注意,当扫描目标字符串时,从座到右尝试匹配这些被'|'分隔的正则表达式,一旦一个模式被完全匹配时,后面的模式就不会尝试匹配了。
(...):匹配括号内的任何正则表达式,并指明组的开始和结束;可以在执行匹配后检索组的内容,并可以稍后再字符串中与\number特殊序列匹配。匹配字面上的'('或')',可以使用\(or\)或[(][)]。
2、特殊序列
\number:匹配相对应组号的内容。组号从1开始(例如,(.+) \1匹配'the the'或者'55 55')。该特殊序列智能用于匹配前99个组中的一个。如果第一个数字是0或者是3个八进制数,则不会将其解释为组匹配,而是具有八进制数值的字符。在字符类[]的内部,所有数字都被视为字符。
\A:仅仅匹配字符串开头
\b:仅仅匹配单子的开头或结尾。单子被定义为由Unicode字母数字或下划线组成的序列,因此单词的结果由空格、非字母数字或非下划线Unicode字符表示。注意,\b被定义为\w和\W字符之间的界限(反之亦然),或\w和字符串的开始\结尾之间的界限(例如r'\bfoo \b'匹配'foo'、'foo.'、'(foo)'、'bar foo baz',但不匹配'foobar'或'foo3')。
- 默认情况下,Unicode字符数字就是字符数字,但是可以通过ASCII标志位来更改。在字符范围内,\b表示退格,以便与Python的字符串文本兼容。
 
\B:匹配一个单子不在开头或结尾的字符(例如r'py\B'匹配'python'、'py3'、'py2',但不匹配'py'、'py.'或'py!')。\B与\b相反,所以单词字符是Unicode字母数字或下划线,尽管这可以通过使用ASCII标志来更改。
\d:
- 对于Unicode(str)模式:匹配任何Unicode十进制数字(即Unicode字符类别[Nd]中的任何字符),包括[0-9]和其他数字字符。如果使用ASCII标志,只匹配[0-9](但标志会影响整改正则表达式,因此在这种情况下使用明确的[0-9]可能是更好的选择)
 - 对于8-bit(字节)模式:匹配任何十进制数字,相当于[0-9]
 
\D:匹配任何不是Unicode十进制数字的字符,与\d相反。
\s:
- 对于Unicode(str)模式:匹配Unicode空格字符(包括\t \n \r \f \v,以及其他其他字符),如果使用ASCII标志,只匹配\t \n \r \f \v
 - 对于8-bit(字节)模式:匹配ASCII字符集中被视为空格的字符,等同于[\t\n\r\f\v]
 
\S:匹配任何不是Unicode空格字符的字符,与\s相反。
\w:
- 对于Unicode(str)模式:匹配Unicode字符,这包括可以作为任何语言中的单词的一部分的大多数字符,以及数字和下划线。如果使用ASCII标志,只匹配[a-zA-Z0-9_]
 - 对于8-bit(字节)模式:匹配ASCII字符集中的字符,相当于[a-zA-Z0-9_]
 
\W:匹配任何不是Unicode字符的字符,与\w相反。
\Z:只在字符串的结尾处进行匹配。
二、re模块介绍
1、re.compile(pattern, flags = 0)
将正则表达式模式编译成一个正则表达式对象,匹配时可以调用它的match()和search()方法。其中可以通过指定flags值修改表达式的行为,值可以使任何以下变量,组合使用"|"运算符。
flags:re.A(re.ASCII)、re.DEBUG、re.I(re.IGNORECASE)、re.L(re.LOCALE)、re.M(re.MULTILINE)、re.S(re.DOTALL)、re.X(re.VERBOSE)
2、re.search(pattern, string, flags = 0)
扫描字符串查找正则表达式模式产生匹配的第一个位置,并返回相应的match object,没有匹配则返回None。
3、re.match(pattern, string, flags = 0)
如果字符串开头的零个或多个字符与正则表达式模式相匹配,则返回相应的match object,不匹配则返回None。
4、re.fullmatch*pattern, string, flags = 0)
如果整个字符串与正则表达式模式相匹配,则返回相应的match object,否则返回None。
5、re.split(pattern, string, maxsplit = 0, flags = 0)
按照能够匹配的子串将字符串分割后返回列表。
6、re.findall(pattern, string, flags = 0)
在字符串中找到正则表达式匹配的所有子串,并返回一个列表。(注意match、search都是匹配一次,findall匹配所有)
7、re.finditer(pattern, string, flags = 0)
和findall相似,在啊字符串中找到正则表达式匹配的所有子串,并把结果作为一个迭代器返回。
三、正则表达式对象
re.RegexObject——re.compile()返回的RegexObject对象。
re.MatchObject——re.match()和re.search()返回的MatchObject对象。group()返回被RE匹配的字符串。
四、实例
#!/usr/bin/python
import re
line = "Cats are smarter than dogs"
matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)
if matchObj:
    print("matchObj.group() : ", matchObj.group())
    print("matchObj.group(1) : ", matchObj.group(1))
    print("matchObj.group(2) : ", matchObj.group(2))
else:
    print("No match!!")
##########运行结果##########
matchObj.group() :  Cats are smarter than dogs
matchObj.group(1) :  Cats
matchObj.group(2) :  smarter
                    
                
                
            
        
浙公网安备 33010602011771号