正则基础复习..
Python re模块
re模块是Python正则表达式模块, 能够对字符串进行模式匹配, 抓取内容, 十分常用. 主要有两个类: RegexObject 类(又俗称pattern对象)和 Match 类, 前者是对象化的正则表达式, 后者是匹配和匹配结果对象化.
使用示例:
pattern=re.compile(exp[,flags])
: 将正则表达式编译成Pattern对象, 返回Pattern对象match=pattern.match(string)
: 利用正则表达式在string中进行匹配,返回Match对象. 无法匹配时返回None可以用if match:
去判断. match方法默认是从0开始进行匹配模式, 所以并一定匹配上.match=pattern.search(string)
: search方法与match方法类似, 但”不限于”开头位置, 可以匹配到字符串中间的内容, 所以可以不限制后面的startpos和endpos. 返回也是match对象.if (not match): print match.group()
: 将匹配部分结果打印出来.match匹配不上会返回None所以最好加个判断防出错. group()就是把匹配组打印出来. 如果pattern只有一个组就是这个组咯.
以上匹配/搜索还可以简单化为: re.match/search(exp, string[,flags])
返回match对象. 这种使用re函数方法适用于简单进行匹配, 不需要重复使用匹配pattern对像 (因为没有返回pattern对象).
语法差异
(?P<name>)
: 分组自定义组名时多了个P, 这里name不用’name’, 直接打就可以了(?P=name)
: 引用自定义组名分组匹配到的字符串. (自动分组依然用\num
)(?(id/name)yespattern|nopattern)
: 如果组号为id或者name的组匹配到字符, 则后面需要匹配yespattern,否则就匹配nopattern. nopattern可以省略. 如(\d)abc(?(1)\d|abc)
可以匹配1abc2或者abcabc(?..)
或者(?iLmsux)
: 每个字符代表一个匹配模式,只能用在正则表达式开头,可选多个. (参见re模块的compile的Pattern对象匹配模式部分).这种是非捕获性匹配. (除非(?P=..)
)\\\\和r"\\"
: 都是想表达查找\\
,但是后者可用原生字符串r去解决. 建议多用r的表达去写正则表达字符串.
re模块函数
这里的exp是指一个代表正则表达式的字符串, 而不是RegexObject对象. match/search/split/findall/finditer/sub/subn方法都在后面RegexObject对象中进行讨论和例子, 这里不展开.
re.compile(exp[,flags])
:
将正则表达式编译成Pattern对象, 第二个参数是匹配模式(可用|
分隔多个模式). 返回Pattern对象. Pattern对象可以通过相应方法实现很多正则表达式功能. 一般正则表达式需要重用时常使用pattern对象, 否则一般情况使用相应re方法即可.
其中匹配模式:re.compile('exp',re.I |re.M)
等效于re.compile("(?im)exp")
. 匹配模式flags包括:re.I
(re.IGNORECASE): 忽略大小写差异.re.M
(re.MULTILINE): 多行模式, 改变^
,$
的匹配行为re.S
(re.DOTALL): 点任意匹配模式(包括换行), 改变.
的行为re.L
(re.LOCALE): 使预定字符类\w \W \b \B \s \S
取决于当前区域设定re.U
(re.UNICODE): 使预定字符类\w \W \b \B \s \S \d \D
取决于unicode定义的字符属性re.X
(re.VERBOSE): 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。
re.match(exp, string[,flags])
: 使用exp进行从头匹配字符串string.re.search(exp, string[,flags])
:
使用exp进行搜素匹配字符串string.re.split(exp, string[, maxsplit, flags])
:
使用exp匹配的作为分隔符来分隔字符串. 如果exp含有分组, 会保留匹配的字符串到结果的列表.re.findall(exp, string[, flags])
:
使用exp去查证string, 返回所有匹配的子串或者分组情况.re.finditer(exp, string[, flags])
:
返回一个可以查收Match对象的迭代器, 描述string中所有匹配exp的部分.re.sub(exp, repl, string[, count])
:
使用repl来代替string中exp匹配的部分. count是最大替换数. repl可以是字符串可以是函数.re.nsub(exp, repl, string[, count])
:
返回元组(替换后字符串,替换次数)re.escape(string)
:
会把字符串非数字字母的符号变成转义式, 再把转义式的\
再转义. 例如a b
会返回a\\ b
. 尤其适于对匹配表达式的处理.re.purge()
:
清楚正则表达式缓存
RegexObject对象
#### 属性:
1. pattern
: 编译时的表达式字符串
2. flags
: 匹配模式, 数字形式
3. groups
: 表达式中分组数量
4. groupindex
: 表达式中有别名的组的别名为键, 对应组的编号为值得字典. 无别名的组不包含在内.
使用re函数的方法:
match(string[, pos[, endpos]])
:
这个方法将从string的pos下标处起尝试匹配pattern;如果pattern结束时仍可匹配,则返回一个Match对象;如果匹配过程中pattern无法匹配,或者匹配未结束就已到达endpos,则返回None。pos和endpos的默认值分别为0和len(string). match是位置锁定(给定位置从头开始匹配)的匹配.search(string[, pos[, endpos]])
:
这个方法用于查找字符串中可以匹配成功的第一个子串。从string的pos下标处起尝试匹配pattern,如果pattern结束时仍可匹配,则返回一个Match对象;若无法匹配,则将pos加1后重新尝试匹配;直到pos=endpos时仍无法匹配则返回None。 search是位置不定搜索串的匹配.split(string[, maxsplit])
:
按照能够匹配的子串将string分割后返回列表(即匹配式作为分隔符)。maxsplit用于指定最大分割次数,不指定(默认0)将全部分割。
如果pattern里面有分组, 返回的列表中将会包含这些匹配的部分.findall(string[, pos[, endpos]])
:
搜索string,以列表形式返回全部能匹配的子串。 如果RegexObject对象对象含有分组, 返回的内容则是分组相关的列表. 所以可能有三种结果:- 如果没有分组, 返回就是所有对pattern匹配的子串的列表.
- 如果分组数只有一个, 则返回一个列表包括所有能匹配这个分组的部分.
- 如果有多个分组, 则返回一个列表, 里面的元素是元组, 元组每个元素对应每个分组的匹配部分.
finditer(string[, pos[, endpos]])
:
搜索string,返回一个顺序访问每一个匹配结果(Match对象)的迭代器。sub(repl, string[, count])
:
使用repl替换string中每一个匹配的子串后返回替换后的字符串。 count可以限定最大替换次数(0为全部替换,默认). repl可以两种情况:- 当repl是一个字符串时,可以使用
\id
或\g<id>
、\g<name>
引用pattern里面的分组情况,但不能使用编号0。 - 当repl是一个函数名时,这个方法应当只接受一个参数(Match对象),并返回一个字符串用于替换(返回的字符串中不能再引用分组)。count用于指定最多替换次数,不指定时全部替换。
- 当repl是一个字符串时,可以使用
subn(repl, string[, count])
:
返回元组 (sub(repl, string[, count]), 替换次数), 即(替换后字符串, 替换次数)。
## match and search
s="www.baidu.com"
p1=re.compile("www")
p2=re.compile("com")
p1.match(s).group()
>> 'www'
p1.search(s).group()
>> 'www'
p2.match(s)
>> None
p2.search(s).group()
>> 'com'
## split
p=re.compile('\W+')
p.split('Words, words, words.')
>> ['Words', 'words', 'words', '']
p=re.compile('(\W+)')
p.split('Words, words, words.')
>> ['Words', ', ', 'words', ', ', 'words', '.', '']
## findall
p0=re.compile('go(?:to|ing)')
p0.findall("goto find going where found high")
>> ['goto', 'going']
p1=re.compile('go(to|ing)')
p1.findall("goto find going where found high")
>> ['to', 'ing']
p2=re.compile('go(to|ing).*?(f.*?\W)')
p2.findall("goto find going where found high")
>> [('to', 'find '), ('ing', 'found ')]
## sub
re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',
r'static PyObject*\npy_\1(void)\n{',
'def myfunc():')
>> 'static PyObject*\npy_myfunc(void)\n{'
def dashrepl(matchobj):
if matchobj.group(0) == '-': return ' '
else: return '-'
re.sub('-{1,2}', dashrepl, 'pro----gram-files')
>> 'pro--gram files'
re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE)
>> 'Baked Beans & Spam'
Match对象
属性:
string
: 匹配时使用的文本。re
: 匹配时使用的Pattern对象。pos
: 文本中正则表达式开始搜索的索引。值与Pattern.match()和Pattern.seach()方法的同名参数相同。endpos
: 文本中正则表达式结束搜索的索引。值与Pattern.match()和Pattern.seach()方法的同名参数相同。lastindex
: 最后一个被捕获的分组在文本中的索引。如果没有被捕获的分组,将为None。lastgroup
: 最后一个被捕获的分组的别名。如果这个分组没有别名或者没有被捕获的分组,将为None。
方法:
group([group1, …])
:
获得一个或多个分组截获的字符串;指定多个参数时将以元组形式返回。group1可以使用编号也可以使用别名;编号0代表整个匹配的子串;不填写参数时,返回group(0);没有截获字符串的组返回None;截获了多次的组返回最后一次截获的子串。groups([default])
:
以元组形式返回全部分组截获的字符串。相当于调用group(1,2,…last)。default表示没有截获字符串的组以这个值替代,默认为None。groupdict([default])
:
返回以有别名的组的别名为键、以该组截获的子串为值的字典,没有别名的组不包含在内。default含义同上。start([group])
:
返回指定的组截获的子串在string中的起始索引(子串第一个字符的索引)。group默认值为0。end([group])
:
返回指定的组截获的子串在string中的结束索引(子串最后一个字符的索引+1)。group默认值为0。span([group])
:
返回(start(group), end(group))。expand(template)
:
将匹配到的分组使用template进行替换然后返回替换后字符串, 详细参考re.sub
方法。template中可以使用\id
或\g<id>
、\g<name>
引用分组,但不能使用编号0。\id
与\g<id>
是等价的;但\10
将被认为是第10个分组,如果你想表达\1
之后是字符’0’,只能使用\g<1>0
。