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))
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
(pattern, string, flags=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)]
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).
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() Token | Regular 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]