一、正则(re)
就其本质而言,正则表达式(或re)就是一种小型的、高度专业化的编程语言,它内嵌在python中,并通过re模块实现。
正则表达式模式被编译成一系列的字节码,然后由用c语言编写的匹配引擎执行。
用途:模糊匹配
元字符:. ^ $ * + ? {} [] | ()
♦通配符 ‘ . ’(除 以外都可以代替)
一个点代表一个其它任意字符
两个点代表2个字符
<以下程序都是在pycharm交互环境下运行>
findall 会匹配所有内容,符合条件的都返回到一个列表
import re re. findall("a..x", "asdasdxdf") ['asdx']
♦ ^ :以...开头(只能在开头匹配)
re.findall("^a..x", "adsxdfdfhu") ['adsx']
重复符:* + ? {}
♦ * :匹配(0,+00)次 属于贪婪匹配
re.findall("alex*", "asdsadalexxx") ['alexxx']
re.findall("alex*", "asdsadale") ['ale']
♦ + :匹配(1,+00)次 (+号前的字符必须出现一次,才能匹配到)属于贪婪匹配
re.findall("alex+", "asdsadalexxx") ['alexxx']
re.findall("alex+", "asdsadale") [] #空列表表示没有匹配到
♦ ?:匹配(0, 1)次
re.findall("alex?", "asdsadalexxx") ['alex']
re.findall("alex?", "asdsadale") ['ale']
♦ { }
{0,} == *
{1, } == +
{0, 1} == ?
{n}: 重复n次
{1,n} :重复1 - n次 (1和n 之间只用逗号,不要用空格)
{1,n} :重复1 - n次 (1和n 之间只用逗号,不要用空格)
{0,n} :重复0 - n次 (0和n 之间只用逗号,不要用空格)
re.findall("alex{6}", "asdbhalexx") []
re.findall("alex{6}", "asdbhalexxxxxx") ['alexxxxxx']
re.findall("alex{1,6}", "asdbhalexxx")
['alexxx']
♦惰性匹配: * + 加上 ?
re.findall("alex*?", "asdasdalexxx") #匹配0次 ['ale'] re.findall("alex+?", "asdasdalexxx") #匹配1次 ['alex']
♦字符集 [ ] ,里面写多个字母表示或的关系
在字符集里有功能的符号 - ^
在字符集除了上面三个符号,没有别的特殊功能符号
re.findall("x[yz]", "xyuuuu") #表示或的关系 ['xy'] re.findall("x[yz]", "xyuxzu") ['xy', 'xz']
re.findall("www[baidu]", "wwwbaidu") ['wwwb']
re.findall("x[yz]p", "xypuuxzpuzyzp") ['xyp', 'xzp']
re.findall("x[y,z]p", "xypuuxzpux,p") #逗号当普通字符处理 ['xyp', 'xzp', 'x,p']
re.findall("x[y*z]p", "xypuuxzpux*p") #星号当普通字符处理 ['xyp', 'xzp', 'x*p']
♦ - :
[A-Z]:表示A到Z的其中一个
[a - z]:表示a到z的其中一个
re.findall("q[a-z]", "qu") #a - z的其中一个 ['qu'] re.findall("q[a-z]", "quo") ['qu']
re.findall("q[a-z]*", "quosdsa") #重复中括号里的内容匹配 ['quosdsa'] re.findall("q[a-z]+", "quosdsa") ['quosdsa']
re.findall("q[0-9]", "qsdfdasf8") # 0- 9中的其中一个 [] re.findall("q[0-9]*", "qsdfdasf8") ['q']
re.findall("q[0-9]*", "q9sdfdasf8") ['q9']
re.findall("q[0-9]*", "q9235345sdfdasfq8") ['q9235345', 'q8']
♦ ^放到 [ ] 中表示非
re.findall("q[^a-z]", "q123") #匹配只要不是a- z ['q1'] re.findall("q[^a-z]", "qzsd") []
re.findall("([^()]*)", "12+(34*6+2-5*(2-1))") ['(2-1)']
元字符之转义字符
反斜杠后跟元字符去除特殊功能,比如 .
反斜杠后跟普通字符实现特殊功能,比如d
d 匹配任何十进制数;它相当于类[0 - 9]
D 匹配任何非数字字符;它相当于类[^0-9]
s匹配任何空白字符;它相当于类[+ fv]
S匹配任何非空白字符;它相当于类[^+ fv]
w匹配任何字母数字字符;它相当于类[a-zA-Z0-9]
W匹配任何非字母数字字符;它相当于类[^a-zA-Z0-9]
匹配一个特殊字符边界,比如空格,&,#等
例:
re.findall("d","12 + (34*6+2-5*(2-1))" ) ['1', '2', '3', '4', '6', '2', '5', '2', '1'] re.findall("d+","12 + (34*6+2-5*(2-1))" ) ['12', '34', '6', '2', '5', '2', '1']
re.findall("www.baidu","www.baidu" ) ['www.baidu'] re.findall("www.baidu", "www baidu") [] re.findall("www.baidu","www.baidu" ) ['www.baidu']
re.findall("www*baidu", "www*baidu") [] re.findall("www*baidu", "www*baidu") ['www*baidu']
在python和re环境中都有转义的意义,而下面需要的是普通的斜杠加b,所以得用原生的,此时前面加 r 或再加个斜杠
r" " 后面的内容就是原生内容,不做任何转义
re.findall("I", "hello I Love Ilex") [] re.findall(r"I", "hello I Love Ilex") #取后面有空格的那个I ['I']
re.findall("I\b", "hello I Love Ilex") ['I']
特殊的四斜杠:
因为在re和python中都有转义作用,要得到re中的l,则需要\l 而先经过python环境就需要两个\去转义re需要的两个\,所以变成4个斜杠
re.findall("c\\l", "abclerwt") #匹配cl ['c\l']
re.findall(r"c\l", "abclerwt") #匹配cl ['c\l']
♦ | :或
re.findall("ka|b", "asdkasf") ['ka'] re.findall("ka|b", "asdkabsf") ['ka', 'b'] re.findall("ka|b", "asdkbsf") ['b']
re.findall("ka|b", "asdkbsf") ['b'] re.findall("ka|b", "asdka|bsf") ['ka', 'b'] re.findall("ka|bc", "asdka|bsf") ['ka']
re.findall("ka|bc", "asdka|bcsf") ['ka', 'bc']
♦()分组
re.findall("(abc)+","abcccccccccc") ['abc']
re.findall("(abc)+", "abcabcabcabc") #把abc当成一个整体匹配,但是优先显示括号里的内容 ['abc'] re.findall("(?:abc)+", "abcabcabcabc") #取消()的优先级 ['abcabcabcabc'] re.findall("abc+", "abcabcabcabc") ['abc', 'abc', 'abc', 'abc']
findall :把字符串里所有能匹配的内容放到一个列表
search :找到一个满足条件的就不找了, 匹配成功返回一个对象,用 .group()取值
re.search("[a-z]+", "alex34asd19").group() 'alex'
(?P<组名>正则):分组
re.search("(?P<name>w+)", "alex34").group() 'alex34'
想单独取alex,则:
re.search("(?P<name>[a-z]+)d+", "alex34asd19").group() 'alex34' re.search("(?P<name>[a-z]+)d+", "alex34asd19").group("name") 'alex'
re.search("(?P<name>[a-z]+)(?P<age>d+)", "alex34asd19").group("age") '34'
findall会优先匹配()中的内容
re.findall("www.(baidu|163).com","www.baidu.com") ['baidu']
如果想匹配所有内容,取消权限即可
re.findall("www.(?:baidu|163).com","www.baidu.com") ['www.baidu.com']