python模块-re模块

http://blog.csdn.net/pipisorry/article/details/25909899

正则表达式语法

[正则表达式]


 

re模块常用正则表达式处理函数Module Contents

re选项

re库API中,一般都有flags参数,通过该参数指定正则表达式选项。传递时一般使用简写,比如开启DOTALL和MULTILINE使用re.I|re.M

A  ASCII       使\w\W\b\B\d\D匹配ASCII字符
I  IGNORECASE  忽略大小写
L  LOCALE      使\w\W\b\B匹配本地字符集
M  MULTILINE   多行模式,"^" 匹配每行开头,"$"匹配每行结尾
S  DOTALL      "." 匹配所有字符,包括"\n"
X  VERBOSE     详细模式,忽略空白可以加入注释
U  UNICODE     使\w\W\b\B\d\D匹配unicode字符集

API速查

这里只是列出API,便于查阅,后面会详细介绍API的使用。建议先跳过这一段,直接看后面的Sample,再回过头来看这一段。

API分为三组,第一组是模块API(Module Contents),通过re.xx()使用;第二组是表达式API(Regular Expression Objects),re.complie()函数会返回一个表达式对象,通过该对象使用的函数;第三组是匹配对象API(Match Objects),像search这些函数都会返回一个匹配结果,这组API用于操作结果集。

re库对于很多函数,例如match,都提供了两种调用方式,一是直接通过re库调用,将正则表达式作为参数,二是先用complie编译表达式,通过返回的对象调用,方法二在正则表达式会被多次使用时会减少重复编译花费的时间。

模块APII(Module Contents)

re.compile(pattern, flags=0)                预编译一个正则表达式,返回一个表达式对象(Regular Expression Objects)
re.search(pattern, string, flags = 0)       搜索任意位置的,在字符串中找匹配的串,返回第一个匹配到的匹配对象。
re.match(pattern, string, flags=0)          搜索边界的。从头开始匹配!!!返回匹配对象。只从字串的开始位置进行匹配,如果失败,它就此放弃,这是和search本质区别。
re.fullmatch(pattern, string, flags=0)    搜索的字符与内容全部匹配。py3.4新增。
re.split(pattern, string, maxsplit=0, flags=0)  使用pattern分割字符串,返回一个结果list
re.findall(pattern, string, flags=0)        search加强版,返回所有的匹配对象的list
re.finditer(pattern, string, flags=0)       返回一个match对象的迭代器,用户可以使用迭代器查看所有match对象,通过match对象属性得到匹配对象和ind下标等。
index = [(m.start(), m.end()) for m in re.finditer(skin_patterns, sent)] 查看所有匹配对象的位置
re.sub(pattern, repl, string, count=0, flags=0)  使用repl替换string中pattern匹配到的部分;
                                                 这里repl可以是一个函数,参数是匹配对象,返回要替代的串
re.subn(pattern, repl, string, count=0, flags=0) 类似sub,返回元组(new_string, number_of_subs_made)
re.escape(string)                           将所有的非字母数字字符前加"\"后返回
re.purge()                                  清空正则表达式缓存

表达式API(Regular Expression Objects)
flags                                       编译时的flag
groups                                      表达式中分组的数量
groupindex                                  以有别名的组别名为键、编号为值的字典
pattern                                     编译时用的表达式字符串
search(string[, pos[, endpos]])             从Pos处开始查找字符串,返回匹配对象
match(string[, pos[, endpos]])              从Pos处匹配字符串,返回匹配对象
split(string, maxsplit=0)                   同re.split
findall(string[, pos[, endpos]])            从Pos处查找所有匹配的字符串,返回所有匹配对象的list
finditer(string[, pos[, endpos]])           从Pos处查找所有的字符串,返回一个迭代器
sub(repl, string, count=0)                  同re.sub
subn(repl, string, count=0)                 同re.subn

匹配对象API(Match Objects)
pos                     传递给函数的pos
endpos                  传递给函数的endpos
lastindex               最后一个捕获的group的下标
lastgroup               最后一个捕获的group的名字
re                      调用match或者search的表达式对象
string                  match或者search的字符串
expand(template)        将匹配到的分组代入template中然后返回。template中可以使用\id或\g<id>、\g<name>引用分组
                        注意0不能使用,另外\10将被认为是第10个分组,如果你想表达\1之后是字符'0',只能使用\g<1>0。
group([group1, ...])    获得一个或多个分组截获的字符串;指定多个参数时将以元组形式返回,0代表整个匹配串
groups([default])       以元组形式返回全部分组截获的字符串,相当于调用group((1,2,…n))
groupdict([default])    返回以有别名的组的别名为键、以该组截获的子串为值的字典
start([group])          返回指定组的串在原串中的起始索引
end([group])            返回指定组的串在原串中的结束索引
span([group])           返回(start(group), end(group))

[基于Python官方手册的翻译和整理]

Match Object对象拥有的方法

1.group([group1,…])

返回值:返回匹配到的一个或者多个子组。

参数group1:如果是一个参数,那么结果就是一个字符串,如果是多个参数,那么结果就是一个参数一个item的元组。参数group1的默认值为0(将返回所有的匹配值)。如果groupN参数为0,相对应的返回值就是全部匹配的字符串,如果group1的值是[1…99]范围之内的,那么将匹配对应括号组的字符串。如果组号是负的或者比pattern中定义的组号大,那么将抛出IndexError异常。如果pattern没有匹配到,但是group匹配到了,那么group的值也为None。如果一个pattern可以匹配多个,那么组对应的是样式匹配的最后一个。另外,子组是根据括号从左向右来进行区分的。

示例:
 >m=re.match(“(\w+) (\w+)”,”abcd efgh, chaj”)
 >m.group() # 匹配全部
 ‘abcd efgh’
 >m.group(1) # 第一个括号的子组.
 ‘abcd’
 >m.group(2)
 ‘efgh’
 >m.group(1,2) # 多个参数返回一个元组
 (‘abcd’, ‘efgh’)
 >m=re.match("(?P<first_name>\w+) (?P<last_name>\w+)","sam lee")

m.group(“first_name”) #使用group获取含有name的子组
‘sam’
m.group(“last_name”)
‘lee’

 下面把括号去掉
 >m=re.match(“\w+ \w+”,”abcd efgh, chaj”)
 >m.group()
 ‘abcd efgh’
 >m.group(1)
 Traceback (most recent call last):File “pyshell#32>”, line 1, in m.group(1) IndexError: no such group
如果一个组匹配多个,那么仅仅返回匹配的最后一个的(If a group matches multiple times, only the last match is accessible)。
 >m=re.match(r”(..)+”,”a1b2c3”)
 >m.group(1)
 ‘c3’
 >m.group()
 ‘a1b2c3’

2.groups([default])

 返回一个包含所有子组的元组。Default是用来设置没有匹配到组的默认值的。Default默认是”None”,
 >m=re.match(“(\d+).(\d+)”,”23.123”)
 >m.groups()
 (‘23’, ‘123’)
 >m=re.match(“(\d+).?(\d+)?”,”24”) #这里的第二个\d没有匹配到,使用默认值”None”
 >m.groups()
 (‘24’, None)
 >m.groups(“0”)
 (‘24’, ‘0’)

3.groupdict([default])

 返回匹配到的所有命名子组的字典。Key是name值,value是匹配到的值。参数default是没有匹配到的子组的默认值。这里与groups()方法的参数是一样的。默认值为None
 >m=re.match(“(\w+) (\w+)”,”hello world”)
 >m.groupdict()
 {}
 >m=re.match(“(?P\w+) (?P\w+)”,”hello world”)
 >m.groupdict()
 {‘secode’: ‘world’, ‘first’: ‘hello’}
通过上例可以看出,groupdict()对没有name的子组不起作用

[Match Objects]

re常用模块

re.compile(pattern, flags=0)

re.compile 可以把正则表达式编译成一个正则对象。可以把那些经常使用的正则表达式编译成正则表达式对象,这样可以提高一定的效率。在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。但是一般不要在方法体内定义。

Compile a regular expression pattern into a regular expression object, whichcan be used for matching using its match() andsearch() methods.

help(re.compile)
compile(pattern, flags=0)

第一个参数:规则
第二个参数:标志位
实例:

test=”Hi, nice to meet you where are you from?”
k=re.compile(r’\w*o\w*’) #匹配带o的字符串
dir(k)
[‘copy‘, ‘deepcopy‘, ‘findall’, ‘finditer’, ‘match’, ‘scanner’, ‘search’, ‘split’,’sub’, ‘subn’]
print k.findall(test) #显示所有包涵o的字符串
[‘to’, ‘you’, ‘you’, ‘from’]
print k.sub(lambdam: ‘[‘+m.group(0) +’]’,test) # 将字符串中含有o的单词用[]括起来
Hi, nice [to] meet [you] where are [you] [from]?

[Regular Expression Objects]

re.search(pattern, string, flags=0)

re.search 函数会在字符串内查找模式匹配(不需要全匹配),直到找到第一个匹配然后返回一个对象k。return a corresponding match object.

k.group(0)代表整个匹配模式对应的字符串,k.group(1)代表匹配模式中的组对应的字符串

如果字符串没有匹配,则返回None。

help(re.search)
search(pattern, string, flags=0)
第一个参数:规则
第二个参数:表示要匹配的字符串
第三个参数:标致位,用于控制正则表达式的匹配方式

实例:下面的例子kuangl
name=”Hello,My name is kuangl,nice to meet you…”
k=re.search(r’k(uan)gl’,name)
if k:
… print k.group(0),k.group(1)
… else:
… print ”Sorry,not search!”

kuangl uan

re.match(pattern, string, flags=0)

re.match 尝试从字符串的开始匹配一个模式,不需要全匹配!return a corresponding match object.

help(re.match)
match(pattern, string, flags=0)

第一个参数:规则
第二个参数:表示要匹配的字符串
第三个参数:标致位,用于控制正则表达式的匹配方式 

实例1:下面的例子匹配Hello单词

name=”Hello,My name is kuangl,nice to meet you…”
k=re.match(r”(\H….)”,name)
if k:
… print k.group(0),’\n’,k.group(1)
… else:
… print “Sorry,not match!”

Hello
Hello

re.match与re.search的区别:re.match从字符串的开始匹配一个模式,且不需要全匹配,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配,也不需要全匹配。

re.fullmatch(pattern, string, flags=0)

搜索的字符与内容全匹配。py3.4新增。

判断字符串i是否是一个数字串

if re.fullmatch('\d+', i)

re.split(pattern, string, maxsplit=0, flags=0)

re.split 用于来分割字符串

help(re.split)
split(pattern, string, maxsplit=0)

第一个参数:规则
第二个参数:字符串
第三个参数:最大分割字符串,默认为0,表示每个匹配项都分割
实例:分割所有的字符串

test=”Hi, nice to meet you where are you from?” 
re.split(r”\s+”,test) 
[‘Hi,’, ‘nice’, ‘to’, ‘meet’, ‘you’, ‘where’, ‘are’, ‘you’, ‘from?’] 
re.split(r”\s+”,test,3) #分割前三个 
[‘Hi,’, ‘nice’, ‘to’, ‘meet you where are you from?’]

python使用多个分隔符分割字符串

下面是使用汉语标点符号[。!?,]和英文标点符号[!?,]以及微博转发符号“//@”作为断句的分隔符的示例

line = '地丁 一。雪!地陪?霜 ,阿!地?地址,鄄鄄//@村鄄李' print(re.split(r'[。!?,!?,]|//@', line))

['地丁 一', '雪', '地陪', '霜 ', '阿', '地', '地址', '鄄鄄', '村鄄李']

re.findall(pattern, string, flags=0)

re.findall 在目标字符串查找符合规则的字符串

help(re.findall)
findall(pattern, string, flags=0)

第一个参数:规则
第二个参数:目标字符串
但三个参数:后面还可以跟一个规则选择项
返回的结果是一个列表:如果有括号()分组,则返回所有分组tuple的列表(如果其它|分割的规则中没有(),则对应为'',所以最好不要同时使用()和|规则);如果没有括号()分组,则列表中存放的是符合规则的字符串;如果没有符合规则的字符串找到,就会返回一个空值。

示例0:用于字符串分割

[使用正则表达式分割]

示例1

s = 'aaa111k222aaa , bbb222 , 333ccc '
print(re.findall(r'[a-z]+(\d+)k(\d+)[a-z]+', s))    #有多个分组则返回的是[(tuple)],否则返回[string]

[('111', '222')]
示例2:查找邮件账号

mail='<user01@mail.com> <user02@mail.com> user04@mail.com'
print(re.findall(r'(\w+@m....[a-z]{3})',mail))

['user01@mail.com', 'user02@mail.com', 'user04@mail.com']

示例3:

post_ori_text = r'sinaSSOController.preloginCallBack({"retcode":0,"servertime":1441512360,"pcid":"gz-da3c627b7b8260ba5cfd453f4eb3347ca01f","nonce":"9OZ4S7","pubkey":
"EB2A385686618****","rsakv":"1330428213","exectime":3})'
re.findall('{"retcode":(.*?),"servertime":(.*?),"pcid":"(.*?)","nonce":"(.*?)","pubkey":"(.*?)","rsakv":"(.*?)","exectime":(.*?)}', post_ori_text, re.I)[0]

上面 的结果为(u'0', u'1441512470', u'gz-eae72a8b0f6be469f4ac627ca38f7069d5c5', u'D2HXK0', u'EB2A38568661887FA18******', u'1330428213', u'2')

示例4:和re.finditer示例对比:

text = "He was carefully disguised but captured quickly by 10 caps."
print(re.findall(r"ca(p)|gui", text))
for i in re.finditer(r"ca(p)|gui", text):print(i)
['', 'p', 'p']
<_sre.SRE_Match object; span=(20, 23), match='gui'>
<_sre.SRE_Match object; span=(31, 34), match='cap'>
<_sre.SRE_Match object; span=(54, 57), match='cap'>

Note: 规则中有()时,findall大致等效于以下finditer()代码:[i for m in re.finditer(r"ca(p)", text) for i in m.groups()]。

[为什么使用括号时re.findalll和re.finditer的输出不同? [重复]]

re.finditer(pattern, string, flags=0)

返回一个迭代器(元素为match对象),用户可以使用迭代器查看所有匹配对象。

Note: 打印匹配对象时,它返回包含整个匹配字符串的第一个匹配组。即直接print match对象相当于print(match.group(0))。所以会出现上面示例4中findall返回['p','p'],而finditer返回两个“ cap”。

查看所有匹配对象的位置,重叠匹配,lookahead将这样做
index = [(m.start(), m.end()) for m in re.finditer(skin_patterns, sent)]

查看所有匹配对象及其位置

[(i.group(0), i.span()) for i in re.finditer(pattern, query)]

查找所有没有重叠,你可以结合正反面lookahead到一个表达式像这样:

>>> search = 'tt'
>>> [m.start() for m in re.finditer('(?=%s)(?!.{1,%d}%s)' % (search, len(search)-1, search), 'ttt')]
[1]

[re.finditer(patternstringflags=0)

re.sub(pattern, repl, string, count=0, flags=0)

re.sub 用于替换字符串的匹配项。If the pattern isn’t found,string is returned unchanged.

第一个参数:规则
第二个参数:替换后的字符串
第三个参数:字符串
第四个参数:替换个数。默认为0,表示每个匹配项都替换

第二个参数:repl
repl,就是replacement,被替换的字符串的意思。repl可以是字符串,也可以是函数。
repl是字符串
如果repl是字符串的话,其中的任何反斜杠转义字符,都会被处理的。
\n:会被处理为对应的换行符;
\r:会被处理为回车符;
其他不能识别的转移字符,则只是被识别为普通的字符:
比如\j,会被处理为j这个字母本身;
反斜杠加g以及中括号内一个名字,即:\g<name>,对应着命了名的组,named group

repl是函数

import re;
def pythonReSubDemo():
    inputStr = "hello 123 world 456";
     
    def _add111(matched):
        intValue = int(matched.group("number"))
        return str(intValue + 111)
        
    replacedStr = re.sub("(?P<number>\d+)", _add111, inputStr);
    print replacedStr

    #hello 234 world 567

In string-type repl arguments, in addition to the character escapes andbackreferences described above,\g<name> will use the substring matched by the group named name, asdefined by the (?P<name>...) syntax. \g<number> uses the correspondinggroup number; \g<2> is therefore equivalent to \2, but isn’t ambiguousin a replacement such as \g<2>0. \20 would be interpreted as areference to group 20, not a reference to group 2 followed by the literalcharacter '0'. The backreference \g<0> substitutes in the entiresubstring matched by the RE.

示例(使用组和原始字符串)

import os
import re

origin_str = '..bin/clang -g  -DUNDEF_THREADS_HACK -c -o chared.o chared.c'
dir = 'path'
new_str = re.sub('-c', '-emit-llvm -c', origin_str)
new_str = re.sub('(-o\s*)(.*?\.o)', r'\1' + os.path.join(dir, r'\2') + '.bc', new_str)
print(new_str)
../bin/clang -g  -DUNDEF_THREADS_HACK -emit-llvm -c -o path/chared.o.bc chared.c

[re.sub(pattern, repl, string, count=0, flags=0)]

[详解Python中re.sub]

re.subn(pattern, repl, string, count=0, flags=0)

Perform the same operation as sub(), but return a tuple (new_string,number_of_subs_made).

皮皮Blog

re其它部分

Simulating scanf()

Python does not currently have an equivalent to scanf(). Regularexpressions are generally more powerful, though also more verbose, thanscanf() format strings. The table below offers some more-or-lessequivalent mappings between scanf() format tokens and regularexpressions.

scanf() TokenRegular Expression
%c.
%5c.{5}
%d[-+]?\d+
%e, %E, %f, %g[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?
%i[-+]?(0[xX][\dA-Fa-f]+|0[0-7]*|\d+)
%o[-+]?[0-7]+
%s\S+
%u\d+
%x, %X[-+]?(0[xX])?[\dA-Fa-f]+

[Simulating scanf()]

from:python模块-re模块_python 前向界定与后向界定_-柚子皮-的博客-CSDN博客

ref: [re — Regular expression operations]

[re --- 正则表达式操作]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值