一、正则
1. 字符
元字符 | 匹配内容 |
---|---|
. | 匹配出换行外任意字符 |
\w | 匹配字母或数字或下划线 |
\s | 匹配任意空白符 |
\d | 匹配数字 |
\n | 匹配一个换行符 |
\t | 匹配一个制表符 |
\b | 匹配一个单词的结尾 |
^ | 匹配指定字符的开始 |
$ | 匹配字符串的结尾 |
\W | 匹配非字母数字下划线 |
\D | 匹配非数字 |
\S | 匹配非空白符 |
a | b | 匹配字符a或字符b |
() | 匹配括号内的表达式,也是一个组 |
[...] | 匹配字符组中的字符 |
[^...] | 匹配除了字符组中的字符其他所有字符 |
2. 量词
量词 | 匹配内容 |
---|---|
* | 重复0或更多次 |
+ | 重复1或更多次 |
? | 重复0或1次 |
{n} | 重复n次 |
{n, } | 重复n或更多次 |
{n, m} | 重复n到m次 |
3. 运用
import re string_test = "hello" (1) . string_1 = re.findall('.', string_test) print(string_1) >['h', 'e', 'l', 'l', 'o'] (2) ^ string_2 = re.findall('^h', string_test) print(string_2) >['h'] (3) $ string_3 = re.findall('o$', string_test) print(string_3) >['o'] (4) * - 当匹配单个字符的时候,会因为匹配0次而出现空字符 string_test = "hello llo lw" string_1 = re.findall('l*', string_test) print(string_1) >['', '', 'll', '', '', 'll', '', '', 'l', '', ''] string_test = "hello llo lw" string_1 = re.findall('ll*', string_test) print(string_1) >['ll', 'll', 'l'] (5) + string_test = "hello llo lw" string_1 = re.findall('l+', string_test) print(string_1) >['ll', 'll', 'l'] string_test = "hello llo lw" string_1 = re.findall('ll+', string_test) print(string_1) >['ll', 'll'] (6) ? string_test = "hello llo lw" string_1 = re.findall('l?', string_test) print(string_1) >['', '', 'l', 'l', '', '', 'l', 'l', '', '', 'l', '', ''] string_test = "hello llo lw" string_1 = re.findall('ll?', string_test) print(string_1) >['ll', 'll', 'l'] (7) {n, } str1='iii amiiii ssdii iihjf iiifgfdgi ' str2=re.findall('ii{2,}',str1) print(str2) >['iii', 'iiii', 'iii'] (8) {, m} str1='iii amiiii ssdii iihjf iiifgfdgi ' str2=re.findall('ii{,2}',str1) print(str2) >['iii', 'iii', 'i', 'ii', 'ii', 'iii', 'i'] (9) {n, m} str1='iii amiiii ssdii iihjf iiifgfdgi ' str2=re.findall('ii{1,2}',str1) print(str2) >['iii', 'iii', 'ii', 'ii', 'iii'] (10) \d str1='iii amiiii 123er45vg44 ' str2=re.findall(r'\d',str1) print(str2) >['1', '2', '3', '4', '5', '4', '4'] (11) \w str1='iii am_你好iiii 123er45vg44 ' str2=re.findall(r'\w',str1) print(str2) >['i', 'i', 'i', 'a', 'm', '_', '你', '好', 'i', 'i', 'i', 'i', '1', '2', '3', 'e', 'r', '4', '5', 'v', 'g', '4', '4'] (12) \s str1='iii am_你好iiii 123\ner\t45vg44 ' str2=re.findall(r'\s',str1) print(str2) >[' ', ' ', '\n', '\t', ' '] (13) \b str1='i love python ' str2=re.findall(r'\bon',str1) str3=re.findall(r'on\b',str1) print(str2) print(str3) >[] >['on'] (14) \D str1='i love python12456' str2=re.findall(r'\D',str1) print(str2) >['i', ' ', 'l', 'o', 'v', 'e', ' ', 'p', 'y', 't', 'h', 'o', 'n'] (15) \S str1='i love python12456\n\t' str2=re.findall(r'\S',str1) print(str2) >['i', 'l', 'o', 'v', 'e', 'p', 'y', 't', 'h', 'o', 'n', '1', '2', '4', '5', '6'] (16) \W str1='i love ¥%*python12456\n\t' str2=re.findall(r'\W',str1) print(str2) >[' ', ' ', '¥', '%', '*', '\n', '\t'] (17) \B str1='i love python12456' str2=re.findall(r'ov\B',str1) print(str2) >['ov'] (18) []字符集 str1='i love python12456' str2=re.findall(r'[a-z]',str1) print(str2) >['i', 'l', 'o', 'v', 'e', 'p', 'y', 't', 'h', 'o', 'n'] str1='i love python12456' str2=re.findall(r'[^\d]',str1) print(str2) >['i', ' ', 'l', 'o', 'v', 'e', ' ', 'p', 'y', 't', 'h', 'o', 'n'] (19) | str1='i love python12456\n\n' str2=re.findall(r'[\d|\s]',str1) print(str2) >[' ', ' ', '1', '2', '4', '5', '6', '\n', '\n'] (20) () 分组-标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。只会匹配括号中的内容 str1='i love python12456\n\n' str2=re.findall(r'n(\d)',str1) print(str2) >['1']
二、贪婪与非贪婪匹配
正则表达式通常用于在文本中查找匹配的字符串。Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪则相反,总是尝试匹配尽可能少的字符。在"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪。
1. 贪婪模式
贪婪模式下字符串查找会直接走到字符串结尾去匹配,如果不相等就向前寻找,这一过程称为回溯
import re str1='<table><td><th>贪婪</th><th>贪婪</th><th>贪婪</th></td></table>贪婪' str2=re.findall(r'<.*>',str1) print(str2) >['<table><td><th>贪婪</th><th>贪婪</th><th>贪婪</th></td></table>']
2. 非贪婪模式
非贪婪模式下会自左向右查找,一个一个匹配不会出现回溯的情况
import re str1='<table><td><th>贪婪</th><th>贪婪</th><th>贪婪</th></td></table>贪婪' str2=re.findall(r'<.*?>',str1) print(str2) >['<table>', '<td>', '<th>', '</th>', '<th>', '</th>', '<th>', '</th>', '</td>', '</table>']
三、re模块使用
1. re.A(re.ASCII) 让\w,\W,\b,\B,\d,\D,\s和\S 执行ASCII-只匹配完整的Unicode匹配代替。这仅对Unicode模式有意义,而对于字节模式则忽略。 2. re.I(re.IGNORECASE) 执行不区分大小写的匹配;类似的表达式也[A-Z]将匹配小写字母。 3. re.L(re.LOCALE) 让\w,\W,\b,\B和区分大小写的匹配取决于当前的语言环境。该标志只能与字节模式一起使用。不建议使用此标志,因为语言环境机制非常不可靠,它一次只能处理一种“区域性”,并且仅适用于8位语言环境。默认情况下,Python 3中已为Unicode(str)模式启用了Unicode匹配,并且能够处理不同的语言环境/语言。 4. re.M(re.MULTILINE) 指定时,模式字符'^'在字符串的开头和每行的开头(紧随每个换行符之后)匹配;模式字符'$'在字符串的末尾和每行的末尾(紧接在每个换行符之前)匹配。默认情况下,'^' 仅在字符串的开头,字符串'$'的末尾和字符串末尾的换行符(如果有)之前立即匹配。 5. re.S(re.DOTALL) 使'.'特殊字符与任何字符都匹配,包括换行符;没有此标志,'.'将匹配除换行符以外的任何内容。
1. findall(pattern, string, flags=0)
findall方法,该方法在字符串中查找模式匹配,将所有的匹配字符串以列表的形式返回,如果文本中没有任何字符串匹配模式,则返回一个空的列表,如果有一个子字符串匹配模式,则返回包含一个元素的列表,所以,无论怎么匹配,我们都可以直接遍历findall返回的结果而不会出错。
import re re_str = "hello this is python 2.7.13 and python 3.4.5" pattern = "python [0-9]\.[0-9]\.[0-9]" result = re.findall(pattern=pattern, string=re_str) print(result) >['python 2.7.1', 'python 3.4.5'] # 忽略大小写 re_str = "hello this is python 2.7.13 and Python 3.4.5" pattern = "python [0-9]\.[0-9]\.[0-9]" result = re.findall(pattern=pattern, string=re_str, flags=re.IGNORECASE) print(result) >['python 2.7.1', 'Python 3.4.5']
2. re.compile(pattern, flags=0)
一般采用编译的方式使用python的正则模块,如果在大量的数据量中,编译的方式使用正则性能会提高很多
import re re_str = "hello this is python 2.7.13 and Python 3.4.5" re_obj = re.compile(pattern = "python [0-9]\.[0-9]\.[0-9]",flags=re.IGNORECASE) res = re_obj.findall(re_str) print(res) >['python 2.7.1', 'Python 3.4.5']
3. re.match(pattern, string, flags=0)
match方法,类似于字符串中的startwith方法,只是match应用在正则表达式中更加强大,更富有表现力,match函数用以匹配字符串的开始部分,如果模式匹配成功,返回一个SRE_Match类型的对象,如果模式匹配失败,则返回一个None,因此对于普通的前缀匹配
1. 判断data字符串是否以what、数字开头 import re s_true = "what is a boy" s_false = "What is a boy" re_obj = re.compile("what") print(re_obj.match(string=s_true)) ><_sre.SRE_Match object; span=(0, 4), match='what'> print(re_obj.match(string=s_false)) >None 2. 匹配数字 s_true = "123what is a boy" s_false = "what is a boy" re_obj = re.compile("\d+") print(re_obj.match(s_true)) ><_sre.SRE_Match object; span=(0, 3), match='123'> print(re_obj.match(s_true).start()) >0 print(re_obj.match(s_true).end()) >3 print(re_obj.match(s_true).string) >123what is a boy print(re_obj.match(s_true).group()) >123 print(re_obj.match(s_false)) >None
4. re.search(pattern, string, flag=0)
search方法,模式匹配成功后,也会返回一个SRE_Match对象,search方法和match的方法区别在于match只能从头开始匹配,而search可以从字符串的任意位置开始匹配,他们的共同点是,如果匹配成功,返回一个SRE_Match对象,如果匹配失败,返回一个None,这里还要注意,search仅仅查找第一次匹配,也就是说一个字符串中包含多个模式的匹配,也只会返回第一个匹配的结果,如果要返回所有的结果,最简单的方法就是findall方法,也可以使用finditer方法
print(re.search('\dcom','www.4comrunoob.5com').group()) >4com *注:match和search一旦匹配成功,就是一个match object对象,而match object对象有以下方法: * group() 返回被 RE 匹配的字符串 * start() 返回匹配开始的位置 * end() 返回匹配结束的位置 * span() 返回一个元组包含匹配 (开始,结束) 的位置 * group() 返回re整体匹配的字符串,可以一次输入多个组号,对应组号匹配的字符串。
import re a = "123abc456" print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0)) #123abc456,返回整体 print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1)) #123 print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2)) #abc print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3)) #456 >>>group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3) 列出第三个括号匹配部分
5. re.finditer(pattern, string, flags=0)
搜索string,返回一个顺序访问每一个匹配结果(Match对象)的迭代器。找到 RE 匹配的所有子串,并把它们作为一个迭代器返回
import re re_str = "what is a different between python 2.7.14 and python 3.5.4" re_obj = re.compile("\d{1,}\.\d{1,}\.\d{1,}") for i in re_obj.finditer(re_str): print(i) >> <_sre.SRE_Match object; span=(35, 41), match='2.7.14'> >> <_sre.SRE_Match object; span=(53, 58), match='3.5.4'>
6. re.sub(pattern, repl, string, count)
re模块sub方法类似于字符串中的replace方法,只是sub方法支持使用正则表达式
import re re_str = "what is a different between python 2.7.14 and python 3.5.4" re_obj = re.compile("\d{1,}\.\d{1,}\.\d{1,}") print(re_obj.sub("a.b.c",re_str,count=1)) >what is a different between python a.b.c and python 3.5.4 print(re_obj.sub("a.b.c",re_str,count=2)) >what is a different between python a.b.c and python a.b.c print(re_obj.sub("a.b.c",re_str)) >what is a different between python a.b.c and python a.b.c
7、re.split(pattern, string[, maxsplit])
re模块的split方法和python字符串中的split方法功能是一样的,都是将一个字符串拆分成子字符串的列表,区别在于re模块的split方法能够; maxsplit用于指定最大分割次数,不指定将全部分割
print(re.split('\d+','one1two2three3four4five5')) >['one', 'two', 'three', 'four', 'five', '']
来源:https://www.cnblogs.com/hq82/p/12457899.html