目录
编译正则表达式
re.compile(pattern,flags=0)
pattern.match
pattern.search
pattern.findall
1.正则表达式无圆括号
2.正则表达式中含有1个圆括号
3.正则表达式中含有多个圆括号
pattern.split
pattern.sub
pattern.subn(repl,string,[count=0])
分组
无名分组
有名分组 (?P正则表达式)
一个命名分组
多个命名分组
后向引用
通过默认分组编号进行后向引用
通过命名分组进行后向引用(?P=name)
交换字符串的位置
前向肯定断言(?=pattern)与后向肯定断言(?<=pattern)
前向否定断言(?!pattern)与后向否定断言(?
pattern类的工厂方法,目的是将正则表达式pattern编译成pattern对象,并返回该对象。
将正则表达式编译成一个正则表达式对象,这样做可以提高效率;
第二个参数flag是匹配模式;
使用该pattern模式唯一的好处就是,一处编译,多出复用;
函数作用:这个方法将在字符串string的pos位置开始,尝试匹配pattern(pattern就是通过re.compile()方法编译后返回的对象),如果pattern匹配成功,无论是否达到结束位置endpos,都会返回一个匹配成功后的 Match对象;如果匹配不成功,或者 pattern未匹配结束就达到endpos,则返回None。
参数说明:
string:被匹配的字符串
pos:匹配的起始位置,可选,默认为0
endpos:匹配的结束位置,可选,默认为 len(string)
匹配到的Match对象,我们将使用其具有的 group()方法取出匹配结果。
>>> import re
>>> pattern=re.compile(r"\d") #编译正则表达式
>>> pattern.match("123")
<_sre.SRE_Match object; span=(0, 1), match='1'>
>>> pattern.match("123").group()
'1'
>>> pattern.match("123",2).group() #起始位置为2
'3'
>>> pattern.match("d23") #匹配失败
>>> print (pattern.match("d23"))
None
该方法的作用是在string[pos, endpos]区间从pos下标处开始匹配pattern,如果匹配成功,返回匹配成功的Match对象;如果没有匹配成功,则将pos加1后重新尝试匹配,直到 pos=endpos时仍无法匹配则返回None
参数说明:
string:被匹配的字符串
pos:匹配的起始位置,可选,默认为0
endpos:匹配的结束位置,可选,默认为len(string)
也就是说如果不指定pos和endpos这两个参数的话,该方法会扫描整个字符串
>>> import re
>>> pattern=re.compile(r"\d+\s?")
>>> pattern.search("we12 346")
<_sre.SRE_Match object; span=(2, 5), match='12 '>
>>> pattern.search("we12 346").group()
'12 '
>>> pattern.search("we12 346",5).group()
'346'
函数作用: 该方法的作用是在string[pos, endpos]区间从pos下标处开始查找所有满足pattern的子串,直到endpos位置结束,并以列表的形式返回查找的结果,如果未找到则返回一个空列表
参数说明:
string:被匹配的字符串
pos:匹配的起始位置,可选,默认为0
endpos:匹配的结束位置,可选,默认为len(string) --->开区间
也就是说如果不指定pos和endpos这两个参数的话,该方法会在整个字符串中查找所有满足 条件的子串。
import re
"找到正则表达式匹配的前10个字母中的所有数字"
pattern=re.compile(r"\d+")
result=pattern.findall("adf324sdf34vsdaf5634",0,10)
print (result)
import re
"查找字符串中所有的数字子串"
matchStr = 'adsd12343.jl34d5645fd789'
#pattern=re.compile(r".*?(\d+).*?")
pattern=re.compile(r"(\d+)")
result=pattern.findall(matchStr)
print (result)
#当正则表达式中只带有一个圆括号时,列表中的元素为字符串,并且该字符串的内容与括号中的正则表达式相对应,并且整个返回的结果都是圆括号中的内容,而不是整个正则表达式匹配的内容
import re
"提取字符串中所有的有效的域名地址"
add = 'https://www.net.com.edu//action=?asdfsd and other https://www.baidu.com//a=b'
pattern=re.compile(r"((w{3}\.)(\w+\.)+(com|edu|cn|net))")
result=pattern.findall(add)
print (result)
“提取字符串中所有的网址”
import re
add = 'https://www.net.com.edu//action=?asdfsd and other https://www.baidu.com//a=b'
pattern=re.compile(r"https://?w{3}\.\w+\.\w+\.?\w+")
result=pattern.findall(add)
print (result)
pattern.split(string[, maxsplit = 0])
函数作用:
分割字符串,将字符串string用给定的正则表达式匹配的字符串进行分割,并返回分割后的结果list。
参数说明:
string:被匹配的字符串
maxsplit:用于指定最大分割次数,可选,默认为0,表示全部分割
import re
pattern=re.compile(r"\d+")
“不指定分割次数”
result=pattern.split("one1two2three3four4")
print (result[:-1])
“指定分割次数”
result1=pattern.split("one1two2three3four4",2)
print (result1)
pattern.sub(repl, string[, count = 0])
参数说明:
repl:用于替换的字符串
string:要被替换的字符串
count:替换的次数,如果为0表示替换所有匹配到的字串,如果是1表示替换1次,为2替换2次等,该参数必须是非负整数,默认为0
import re
p = re.compile(r'(\w+) (\w+)')
s = "i say, hello world!"
print (p.sub(r"\2 \1",s))
def func(m):
#print (m.group())
return m.group(1).title() + ' ' + m.group(2).title()
print (p.sub(func, s))
subn用法和sub函数用法相似,不过结果返回一个tuple,tuple第一个元素是替换后的新字符串,第二个元素是替换的次数
import re
p = re.compile(r'[^\w|\s]+')
"去掉语句加的特殊符号"
s = "^&&today&(is%%#fine# day!"
result= p.subn(" ", s)
print (result)
print ("替换后的新字符串为%s" % result[0])
print ("替换次数为%s" % result[1])
分组就是用一对圆括号“()”括起来的正则表达式,匹配出的内容就表示一个分组。从正则表达式的左边开始看,看到的第一个左括号“(”表示表示第一个分组,第二个表示第二个分组,依次类推。需要注意的是,有一个隐含的全局分组(就是索引号为0的分组),就是整个正则表达式匹配的结果
import re
s = u'更多 dfsl
'
result=re.search(r"(.*)",s).group()
print (result)
result=re.search(r"(.*)",s).group(1)
print (result)
result1=re.match(r".*(.*)",s).group(1) #与上面的正则表达式等价
print (result1)
命名分组就是给具体有默认分组编号的组另外再起一个别名,方便以后的引用。
命令分组的语法格式如下:
(?P
“提取字符串中的ip地址”
import re
s = "ip='230.192.168.78',version='1.0.0'"
res = re.search(r"ip='(?P\d+\.\d+\.\d+\.\d+).*", s)
print (res.group('ip')) #通过命名分组引用分组
import re
s ="phone,number,15817934235"
result=re.search(r"(?P\w+),(?P\w+),(?P\d+)",s)
print (result.group("Last")) #取第一个分组的内容
print (result.group("First")) #取第二个分组的内容
print (result.group("phone")) #取第三个分组的内容
正则表示式中,放在圆括号“()”中的表示是一个分组。然后我们就可以对整个组使用一些正则操作,例如重复操作符。
要注意的是,只有圆括号“()”才能用于形成分组,””用于定义字符串,而”{}”用于定义重复操作。当用”()”定义了一个正则表达式分组后,正则引擎就会把匹配的组按照顺序进行编号,然后存入缓存中。这样我们就可以在后面对已经匹配过的内容进行引用,这就叫后向引用。
后向引用的语法:
\数字:\1表示引用第一个分组,\2引用第二个分组,以此类推,\n引用第n个组,而\0则表示引用整个被匹配的正则表达式本身。
(?P=name) 字符P必须是大写的P,name表示命名分组的分组名。
注意:
这些引用都必须是在正则表达式中才有效,用于匹配一些重复的字符串。
import re
s = 'aaa111aaatestaaa'
print (re.findall(r'([a-z]+)\d+(\1).*(\1)', s))
import re
#后向引用,匹配两个一样的单词,内容必须一致,否则匹配失败
res = re.search(r'(?Pgo)\s+(?P=name)\s+(?P=name)', 'go go go')
#res=re.search(r"(\w+)\s(\1)\s(\2)",s)
print (res.group())
print (res.group('name'))
import re
s="abc.xyz"
#交换.号两边的字符串
result=re.sub(r"(.*)\.(.*)",r"\2.\1",s)
#result=re.sub(r"(\w+)\.(\w+)",r"\2.\1",s)
print (result)
前向肯定断言的语法:
(?=pattern) 前向肯定断言表示你希望匹配的字符串前面是pattern匹配的内容时,才匹配。
后向肯定断言的语法:
(?<=pattern) 后向肯定断言表示你希望匹配的字符串的后面是pattern匹配的内容时,才匹配
如果在一次匹配过程中,需要同时用到前向肯定断言和后向肯定断言时,那必须将前向肯定断言表达式写在要匹配的正则表达式的前面,而后向肯定断言表达式写在要匹配的字符串的后面,表示后向肯定模式之后,前向肯定模式之前
#匹配以a字母为开头的单词
>>> s="abc bcd aed"
>>> re.findall(r"\b(?=a)\w+\b",s)
['abc', 'aed']
#匹配以ing为结尾的单词
>>> import re
>>> s="I'm singing while you're dancing"
>>> re.findall(r"\b\w+(?<=ing)\b",s)
['singing', 'dancing']
前向肯定断言括号中的正则表达式必须是能确定长度的正则表达式,比如\w{3},而不能写成 \w*或者\w+或者\w?等这种不能确定个数的正则模式符。
前向否定断言的语法:
(?!pattern) 前向否定断言表示你希望匹配的字符串的前面不是pattern匹配的内容时,才匹配。
后向否定断言的语法:
(?
#匹配开头不是a的所有单词
>>> import re
>>> s="abc bcd aed"
>>> re.findall(r"\b(?!a)\w+\b",s)
['bcd']
#匹配结尾不是K的所有单词
>>> s="word work work wors"
>>> re.findall(r"\b\w+(?