正则表达式并不是Python的一部分。正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大。得益于这一点,在提供了正则表达式的语言里,正则表达式的语法都是一样的,区别只在于不同的编程语言实现支持的语法数量不同。就其本质而言,正则表达式(或 RE)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现。
. 匹配除了换行符外所有字符 (通配符)
1 2 3 4 | content = 'Abcdefghijklmnopq' test = re.findall(r "b.d" ,content) print (test) [ 'bcd' ] |
^ 以....开头
1 2 3 4 | content = 'Abcdefghijklmnopq' test = re.findall(r "^Abcd" ,content) print (test) [ 'Abcd' ] |
$ 以....结尾
1 2 3 4 | content = 'Abcdefghijklmnopq' test = re.findall(r "nopq$" ,content) print (test) [ 'nopq' ] |
* 匹配0到多次 {0, } 控制它前面的字符
1 2 3 4 | content = 'Abcdefghijklmnopq' test = re.findall(r "A.*e" ,content) print (test) [ 'Abcde' ] |
+ 匹配1到多次 {1, }
1 2 3 4 | content = 'abcdefab111111' test = re.findall(r "ab1+" ,content) print (test) [ 'ab111111' ] |
? 匹配0到1次 {0,1}
1 2 3 4 | content = 'abcdefab111111' test = re.findall(r "ab1?" ,content) print (test) [ 'ab' , 'ab1' ] |
* + ? 都是按照贪婪模式进行匹配 非贪婪模式 需要在后面加个?
1 2 3 4 5 6 7 8 9 10 | content = 'abcdefab111111' test = re.findall(r "ab1+?" ,content) print (test) [ 'ab1' ] re.search(r "a(\d+?)" , "a2345" ).group() = > a2 re.search(r "a(\d*?)" , "a2345" ).group() = > a #如果前后均有限定条件 ?不起作用 re.search(r"a(\d*?)b","a2345b").group() => a2345b |
( ) 组 作为一个整体
1 2 3 4 | content = 'abcdefab111111' test = re.findall(r "(ab1)" ,content) print (test) [ 'ab1' ] |
{ } 重复次数自定义
1 2 3 4 | content = 'abcdefab111111' test = re.findall(r "ab1{3,9}" ,content) print (test) [ 'ab111111' ] |
[ ] 字符集 表示或
字符集里面元字符会失去意义 除了 - \ ^ 3个元字符外
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | content1 = 'wwwwwabdxxxxx' test1 = re.findall(r "a[bc]d" ,content1) print (test1) #['abd'] content2 = 'wwwwwacdxxxxx' test2 = re.findall(r "a[bc]d" ,content2) print (test2) #['acd'] * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * content = 'wwwwwa.xxxxx' test = re.findall(r "a[.]x" ,content) print (test) #['a.x'] content = 'wwwww1234xxxxx' test = re.findall(r "[1-9]" ,content) #1~9的数字 print (test) #['1', '2', '3', '4'] content = 'wwwww1234xxxxx' test = re.findall(r "[^1-9]" ,content) #非1~9的数字 print (test) #['w', 'w', 'w', 'w', 'w', 'x', 'x', 'x', 'x', 'x'] |
\ 作用:
1 2 3 | test = re.search(r "(alex)(eric)com\2" , "alexericcomeric" ) print (test.group()) #alexericcomeric |
\d 匹配任何十进制数, [0-9]
\D 匹配任何非数字字符 [^0-9]
\s 匹配任何空白字符 [ \t\n\r\f\v ]
\S 匹配任何非空白字符 [^ \t\n\r\f\v ]
\w 匹配任何字母数字字符 [a-zA-Z0-9_]
\W 匹配任何非字母数字字符 [^a-zA-Z0-9]
\b 匹配一个单词边界,单词和空格间的位置 匹配特殊字符(不单止空格)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | content = 'wwwww1234xxxxx' test = re.findall(r "\d" ,content) print (test) # ['1', '2', '3', '4'] content = 'ww&*#$%ww1234xx' test = re.findall(r "\D" ,content) print (test) # ['w', 'w', '&', '*', '#', '$', '%', 'w', 'w', 'x', 'x'] content = 'asdasd ' test = re.findall(r "\s" ,content) print (test) # [' ', ' ', ' '] content = ' asdasd ' test = re.findall(r "\S" ,content) print (test) # ['a', 's', 'd', 'a', 's', 'd'] content = 'abc123^&*lm-\_' test = re.findall(r "\w" ,content) print (test) # ['a', 'b', 'c', '1', '2', '3', 'l', 'm', '_'] content = 'abc123^&*lm-\_' test = re.findall(r "\W" ,content) print (test) # ['^', '&', '*', '-', '\\'] content = 'I like Sooooo' test = re.findall(r "like\b" ,content) print (test) # ['like'] * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * test = re.findall(r "abc\b" , "asdasd abc " ) test = re.findall(r "abc\b" , "asdasd abc*" ) print (test) # ['abc'] |
match()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None match(pattern, string, flags = 0 ) # pattern: 正则模型 # string : 要匹配的字符串 # falgs : 匹配模式 # re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同) # M(MULTILINE): 多行模式,改变'^'和'$'的行为 # S(DOTALL): 点任意匹配模式,改变'.'的行为 使 . 匹配包括换行在内的所有字符 # L(LOCALE): 使预定字符类 \w \W \b \B \s \S 取决于当前区域设定 # U(UNICODE): 使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性 # X(VERBOSE): 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。以下两个正则表达式是等价的: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # match对象的方法 .group() 获取匹配到的所有结果 .groups() 获取模型中匹配到的分组结果 .groupdict() 获取模型中匹配到的分组中所有执行了key的组 .group() 返回被RE匹配的字符串 可以加参数group( 1 ) 组号 .start() 返回匹配开始的位置 .end() 返回匹配结束的位置 .span() 返回一个元组包含的匹配的位置 |
search()
1 2 3 4 | # search 匹配成功有结果,返回match对象 # 查看返回结果用.group() # search,浏览整个字符串去匹配第一个,未匹配成功返回None # search(pattern, string, flags=0) |
findall()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | # 优先取组里内容返回! # findall,获取非重复的匹配列表;如果有一个组则以列表形式返回,且每一个匹配均是字符串;如果模型中有多个组,则以列表形式返回,且每一个匹配均是元祖; # 空的匹配也会包含在结果中 # findall(pattern, string, flags=0) data = re.findall( "\d+\w\d+" , 'a2b3c4d5' ) # ['2b3', '4d5'] # re.findall() 匹配成功一个后,从匹配成功最后位置开始下一次查找 # 空的匹配也会包含在结果中 data = re.findall("", 'a2' ) print (data) # ['', '', ''] * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * #有几个括号就取几次 data = re.findall(r '(\dasd)*' , '1asd2asdp3asd3434' ) print (data) # ['2asd', '', '3asd', '', '', '', '', ''] # 贪婪匹配 第一段取到1asd2asd 但最后返回 2asd 取最后一个! 如下: a = "alex" data = re.findall(r '(\w)(\w)(\w)(\w)' ,a) print (data) # [('a', 'l', 'e', 'x')] data = re.findall(r '(\w){4}' ,a) print (data) # ['x'] => 只是执行了4次,返回还是按一个括号算,取最后匹配的一项 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * test = re.findall( "www.(baidu|laonanhai).com" , "asdsa www.baidu.com" ) print (test) # ['baidu'] 添加 ?: 去掉优先权 test = re.findall( "www.(?:baidu|laonanhai).com" , "asdsa www.baidu.com" ) print (test) # ['www.baidu.com'] |
sub()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # sub,替换匹配成功的指定位置字符串 sub(pattern, repl, string, count = 0 , flags = 0 ) # pattern: 正则模型 # repl : 要替换的字符串或可执行对象 # string : 要匹配的字符串 # count : 指定匹配个数 # flags : 匹配模式 test = re.sub( "g.t" , "have" , "I get A, I got B , I gut C" ) print (test) #I have A, I have B , I have C * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * #subn 最后还返回一个替换次数 origin = "ale4 xc 19" data,counts = re.subn( "\d+" , "KKK" ,origin) print (data,counts) # aleKKK xc KKK 2 |
compile()
1 2 3 4 5 | regex = re. compile (r "\w*oo\w*" ) text = " JGood is ,he is cool" data = regex.findall(text) print (data) #['JGood', 'cool'] |
split()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | # split,根据正则匹配分割字符串 split(pattern, string, maxsplit = 0 , flags = 0 ) # pattern: 正则模型 # string : 要匹配的字符串 # maxsplit:指定分割个数 # flags : 匹配模式 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # 有分组情况下, 把分割的项也添加进去 origin = "hello alex bcd alex lge alex acd 19" r1 = re.split( "(alex)" , origin, 1 ) print (r1) # ['hello ', 'alex', ' bcd alex lge alex acd 19'] r2 = re.split( "(al(ex))" , origin, 1 ) print (r2) # ['hello ', 'alex', 'ex', ' bcd alex lge alex acd 19'] * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * p = re. compile (r "\d+" ) test = p.split( "one1two2three3four4" ) print (test) # ['one', 'two', 'three', 'four', ''] # 末尾有空字符串 = > one,two2three3four4 = > [ 'one' ] two,three3four4 = > .. test = re.split( '[bc]' , 'abcd' ) print (test) # ['a', '', 'd'] |
finditer()
1 2 3 4 5 6 7 8 9 10 11 | # 返回结果为迭代对象 p = re. compile (r "\d+" ) w = p.finditer( ' 1 drum44ers druming , 11 ... 10 ...' ) for match in w: print (match.group(),match.span()) # 1 (1, 2) # 44 (7, 9) # 11 (23, 25) # 10 (30, 32) |
与大多数编程语言相同,正则表达式里使用"\"
作为转义字符,这就可能造成反斜杠困扰。
假如你需要匹配文本中的字符"\"
,那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\\\"
前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。
Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r"\\"
表示。
同样,匹配一个数字的"\\d"
可以写成r"\d"
。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。
1 2 3 4 5 6 7 8 | # IP: ^( 25 [ 0 - 5 ]| 2 [ 0 - 4 ]\d|[ 0 - 1 ]?\d?\d)(\.( 25 [ 0 - 5 ]| 2 [ 0 - 4 ]\d|[ 0 - 1 ]?\d?\d)){ 3 }$ # 手机号: ^ 1 [ 3 | 4 | 5 | 8 ][ 0 - 9 ]\d{ 8 }$ # 邮箱: [a - zA - Z0 - 9_ - ] + @[a - zA - Z0 - 9_ - ] + (\.[a - zA - Z0 - 9_ - ] + ) + |
联系客服