正则表达式/ Regular Expression

目录

正则表达式RE(Regular Expression, Regexp, Regex),又称为正规表示法,正规表达式,规则表达式,常规表达式,常规表示法,常简写为regex,regexp或RE。计算机科学的一个概念。正则表达式使用单个字符串来描述或匹配一系列符合某个句法规则的字符串。在许多文本编辑器中,正则表达式常被用于检索、替换那些匹配某个模式的文本。

1正则表达式模式/ RE Pattern

对于正则表达式,其核心与基础是建立起一个正则表达式模式,而一个正则表达式通常由一些特殊字符和符号构成,下面介绍相关的特殊表达式符号与字符。

字符

描述

\

将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“n”匹配字符“n”。“\n”匹配一个换行符。串行“\\”匹配“\”而“\(”则匹配“(”。

^

匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。

$

匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。

*

匹配前面的子表达式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等价于{0,}。

+

匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。

?

匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“does”或“does”中的“do”。?等价于{0,1}。

{n}

n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。

{n,}

n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。

{n,m}

m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。

?

当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。

.

匹配除“\n”之外的任何单个字符。要匹配包括“\n”在内的任何字符,请使用像“(.|\n)”的模式。

(pattern)

匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“\(”或“\)”。

(?:pattern)

匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分是很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。

(?=pattern)

正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。

(?!pattern)

正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始

(?<=pattern)

反向肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。

(?

反向否定预查,与正向否定预查类似,只是方向相反。例如“(?

(?P)

具名匹配子组,以name为标记名的一个匹配子组

(?P=name)

获取具名子组的匹配内容,注意,并非表达式而是匹配成功的内容

(?aiLmsux)

特殊标记参数,可以在正则表达式前嵌入,用于表达式的模式控制,例如“(?im)Python”可以进行忽略大小写,多行模式匹配

(?(id/name)Y|N)

如果分组中提供的id或name存在,则返回正则表达式的条件匹配Y,否则返回N,|N是可选项。

x|y

匹配x或y。例如,“z|food”能匹配“z”或“food”。“(z|f)ood”则匹配“zood”或“food”。

[xyz]

字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。

[^xyz]

负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“p”。

[a-z]

字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。

[^a-z]

负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。

\b

匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。

\B

匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。

\cx

匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。

\d

匹配一个数字字符。等价于[0-9]。

\D

匹配一个非数字字符。等价于[^0-9]。

\f

匹配一个换页符。等价于\x0c和\cL。

\n

匹配一个换行符。等价于\x0a和\cJ。

\r

匹配一个回车符。等价于\x0d和\cM。

\s

匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。

\S

匹配任何非空白字符。等价于[^ \f\n\r\t\v]。

\t

匹配一个制表符。等价于\x09和\cI。

\v

匹配一个垂直制表符。等价于\x0b和\cK。

\w

匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”。

\W

匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。

\xn

匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“\x41”匹配“A”。“\x041”则等价于“\x04&1”。正则表达式中可以使用ASCII编码。.

\num

匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“(.)\1”匹配两个连续的相同字符。

\n

标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。

\nm

标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则\nm将匹配八进制转义值nm。

\nml

如果n为八进制数字(0-3),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。

\un

匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(©)。

2 re模块/ re Module

2.1常量/ Constants

2.1.1 I / IGNORECASE

常量数值: 2

常量功能:忽略大小写的正则表达式模式

2.1.2 L / LOCALE

常量数值: 4

常量功能:使\w, \W, \b, \B取决于当前环境

2.1.3 M / MULTILINE

常量数值: 8

常量功能:多行模式匹配的正则表达式模式

2.1.4 S / DOTALL

常量数值: 16

常量功能:“.”可以匹配换行符“\n”的正则表达式模式

2.1.5 U / UNICODE

常量数值: 32

常量功能:根据Unicode字符集解析字符,影响\w, \W, \b, \B,为默认值,可设为ASCII

2.1.6 X / VERBOSE

常量数值: 64

常量功能:可以抑制空白符的匹配(#为注释符),从而生成更易读的正则表达式模式

2.1.7 A / ASCII

常量数值: 256

常量功能:使\w, \W, \b, \B, \d, \D匹配对应ASCII字符而不是默认的所有Unicode字符

2.2函数/ Function

2.2.1 compile()函数

函数调用: pt = re.compile(pattern, flags=0)

函数功能:对一个正则表达式进行编译,返回一个正则表达式编译对象

传入参数: pattern, flags

pattern: str类型,需要编译的正则表达式

flags: int类型,可传入re的aiLsumx进行模式控制

返回参数: pt

pt: obj类型,编译后的正则表达式类型

Note:通过预编译可以将字符串正则表达式编译成字节码,这将提升使用时的性能,当一个正则表达式多次反复使用时,可进行编译,避免每次使用都要通过字符串进行反复调用与编译。

2.2.2 match()函数

函数调用: pt = re.match(pattern, string, flags=0)

函数功能:从待匹配字符串的开头进行匹配

传入参数: pattern, string, flags

pattern: str/obj类型,正则表达式字符串或对象

string: str类型,待匹配的对象

flags: int类型,可传入re的aiLsumx进行模式控制

返回参数: pt

pt: None/obj类型,匹配后的正则表达式对象,匹配失败返回None

2.2.3 fullmatch()函数

函数调用: pt = re.fullmatch(pattern, string, flags=0)

函数功能:从待匹配字符串的开头进行完全匹配(匹配对象与表达式完全一致)

传入参数: pattern, string, flags

pattern: str/obj类型,正则表达式字符串或对象

string: str类型,待匹配的对象

flags: int类型,可传入re的aiLsumx进行模式控制

返回参数: pt

pt: None/obj类型,匹配后的正则表达式对象,匹配失败返回None

2.2.4 search()函数

函数调用: pt = re.search(pattern, string, flags=0)

函数功能:对待匹配字符串进行搜索匹配

传入参数: pattern, string, flags

pattern: str/obj类型,正则表达式字符串或对象

string: str类型,待匹配的对象

flags: int类型,可传入re的aiLsumx进行模式控制

返回参数: pt

pt: None/obj类型,匹配后的正则表达式对象,匹配失败返回None

2.2.5 sub()函数

函数调用: pt = re.sub(pattern, repl, string, count=0, flags=0)

函数功能:对目标字符串进行模式匹配并替换为指定的字符

传入参数: pattern, repl, string, count, flags

pattern: str/obj类型,正则表达式字符串或对象

repl: str/function类型,替换的字符串或一个可返回字符串的函数

string: str类型,待匹配及替换的对象

count: int类型,替换的数量,默认全部匹配成功的结果都进行替换

flags: int类型,可传入re的aiLsumx进行模式控制

返回参数: pt

pt: None/obj类型,匹配及替换后的正则表达式对象

2.2.6 subn()函数

函数调用: pt = re.subn(pattern, repl, string, count=0, flags=0)

函数功能:对目标字符串进行模式匹配并替换为指定的字符,返回操作数量

传入参数: pattern, repl, string, count, flags

pattern: str/obj类型,正则表达式字符串或对象

repl: str类型,替换的字符串

string: str类型,待匹配及替换的对象

count: int类型,替换的数量,默认全部匹配成功的结果都进行替换

flags: int类型,可传入re的aiLsumx进行模式控制

返回参数: (pt, n)

pt: None/obj类型,匹配及替换后的正则表达式对象

n: int类型,返回进行替换操作的数量

2.2.7 split()函数

函数调用: pt = re.split(pattern, string, maxsplit=0, flags=0)

函数功能:对目标字符串根据正则表达式进行分割

传入参数: pattern, string, maxsplit, flags

pattern: str/obj类型,正则表达式字符串或对象

string: str类型,待匹配及替换的对象

maxsplit: int类型,分割的最大数量,默认分割全部匹配成的位置

flags: int类型,可传入re的aiLsumx进行模式控制

返回参数: pt

pt: list类型,分割后的字符串列表

2.2.8 findall()函数

函数调用: pt = re.findall(pattern, string, flags=0)

函数功能:获取所有(非重复)匹配成功的对象列表

传入参数: pattern, string, flags

pattern: str/obj类型,正则表达式字符串或对象

string: str类型,待匹配的对象

flags: int类型,可传入re的aiLsumx进行模式控制

返回参数: pt

pt: list类型,匹配后的正则表达式对象列表

Note: 若正则表达式pattern中有多个子组,则返回的列表中包含的是一个元组,元组的元素为各个子组匹配的对象

2.2.9 finditer()函数

函数调用: pt = re.finditer(pattern, string, flags=0)

函数功能:获取所有(非重复)匹配成功的对象迭代器

传入参数: pattern, string, flags

pattern: str/obj类型,正则表达式字符串或对象

string: str类型,待匹配的对象

flags: int类型,可传入re的aiLsumx进行模式控制

返回参数: pt

pt: iterator类型,匹配后的正则表达式对象迭代器

2.3类/ Class

2.3.1 __Regex类

类实例化:pass

类的功能:RE类具有re模块的基本函数方法,如search/match/sub等

传入参数: pass

返回参数: pass

2.3.2 __Match类

类实例化:mt=re.match/search(pattern, string, flags=0)

类的功能:用于生成导入图片的实例

传入参数: pattern, string, flags

pattern: str/obj类型,正则表达式字符串或对象

string: str类型,待匹配的对象

flags: int类型,可传入re的aiLsumx进行模式控制

返回参数: pt

pt: None/obj类型,匹配后的正则表达式对象,匹配失败返回None

2.3.2.1 group()方法

函数调用: pt = mt.group(num=0)

函数功能:返回整个匹配对象或者指定的子组

传入参数: num

num: int类型,子组编号

返回参数: pt

pt: str/obj类型,匹配后的正则表达式对象或子组

2.3.2.2 groups()方法

函数调用: pt = mt.groups()

函数功能:返回包含整个匹配对象的元组

传入参数:无

返回参数: pt

pt: tuple类型,匹配后的正则表达式对象或子组元组,无则返回空元组

2.3.2.3 groupdict()方法

函数调用: pt = mt.groupdict()

函数功能:返回包含整个匹配对象中所有具名子组形成的字典

传入参数:无

返回参数: pt

pt: dict类型,匹配后的正则表达式对象或子组字典

2.3.2.4 span()方法

函数调用: pt = mt.span(group=0)

函数功能:返回一个元组,包含匹配结果在被匹配对象中的起始终止位置

传入参数: group

group: int类型,子组编号

返回参数: pt

pt: tuple类型,包含位置信息,(start, end)

3使用正则表达式进行匹配 / RE Match

3.1常用方法示例

下面列举一些re常用的表达式模式以及函数方法的使用示例,

完整代码如下

1 importre2 """

3 Regular Expression4 """

5

6 def regexp(pattern, target, *args, grp='group', prt=True, func='search'):7 pat =re.compile(pattern)8 try:9 r = getattr(getattr(re, func)(pattern, target), grp)(*args)10 exceptAttributeError as e:11 r =None12 #print(e)

13 ifprt:14 print(r)15 returnr16

17 #Use . to match all

18 print(30*'-')19 regexp('.+', 'exit soon') #'exit soon'

20

21 #Use () to make sub-groups

22 print(30*'-')23 regexp('(.+) (.+)', 'exit soon', 1) #'exit'

24 regexp('(.+) (.+)', 'exit soon', 2) #'soon'

25 regexp('(.+) (.+)', 'exit soon', grp='groups') #('exit', 'soon')

26

27 #Use ^ to search from head

28 print(30*'-')29 regexp('^The', 'The End') #'The'

30 regexp('^The', 'In The End') #None

31

32 #Use \b to search boundary

33 print(30*'-')34 regexp(r'\bThe\b', 'In The End') #'The'

35 regexp(r'\bThe', 'In TheEnd') #'The'

36 regexp(r'The\b', 'In TheEnd') #None

37

38 #match and search

39 print(30*'-')40 regexp('The', 'In The End', func='search') #'the'

41 regexp('The', 'In The End', func='match') #None

42

43 #findall and finditer

44 #Note:

45 #findall returns a list that contains string of matched result

46 #finditer returns a iterator that contains obj of matched result

47 #re.IGNORECASE can ignore capitalized

48 print(30*'-')49 print(re.findall('The', 'In The End, these things merged', re.I)) #['The', 'The']

50 itera = re.finditer('The', 'In The End, these things merged', re.I)51 for x initera:52 print(x.group()) #'The'

53

54 #sub and subn

55 print(re.sub('X', 'LIKE', 'This is X, X is acting'))56 print(re.subn('X', 'LIKE', 'This is X, X is acting'))57

58 #split: split(re-expression, string)

59 print(re.split(', |\n', 'This is amazing\nin the end, those things merged')) #['This is amazing', 'in the end', 'those things merged']

60

61 #\N: use \N to represent sub group, N is the number of sub group

62 print(re.sub(r'(.{3})-(.{3})-(.{3})', r'\2-\3-\1', '123-def-789')) #'def-789-123'

63 #(?P): similar to \N, add tag name for each sub group,

64 #and use \g to fetch sub group

65 print(re.sub(r'(?P\d{3})-(?P\d{3})-(?P\d{3})', r'\g-\g-\g', '123-456-789')) #456-789-123

66

67 #(?P=name): use this expression to reuse former sub group result

68 #Note: this expression only get the matched result, not the re pattern

69 print(re.match(r'(?P\d{3})-(?P\w{3})-(?P=char)-(?P=digit)', '123-abc-abc-123')) #Match obj, '123-abc-abc-123'

70 print(re.match(r'(?P\d{3})-(?P\w{3})-(?P=char)-(?P=digit)', '123-abc-def-456')) #None

71

72 #Note: should use (?P=name) in a re expression with former named group

73 print(re.sub(r'(?Ppotato)(XXX)(?P=myName)', r'YY\2YY', 'potatoXXXpotato')) #'YYXXXYY'

74 print(re.sub(r'(?P\d{3})-(?P\w{4})', r'(?P=char)-(?P=digit)', '123-abcd')) #failed:(?P=char)-(?P=digit)

75

76 print(re.sub(r'(?P\d{3})-(?P\w{4})', r'\2-\1', '123-abcd')) #'abcd-123'

77 print(re.sub(r'(?P\d{3})-(?P\w{4})', r'\g-\g', '123-abcd')) #'abcd-123'

78

79

80 #groupdict(): return dict of named pattern

81 print(re.match(r'(?P\d{3})-(?P\w{4})', '123-abcd').groupdict()) #{'char': 'abcd', 'digit': '123'}

82 print(re.match(r'(?P\d{3})-(?P\w{4})', '123-abcd').group('char')) #'abcd'

83 print(re.match(r'(?P\d{3})-(?P\w{4})', '123-abcd').group('digit')) #'123'

84

85 #re extensions

86 #use (?aiLmsux): re.A, re.I, re.L, re.M, re.S, re.X

87 #use (?imsx)

88 #(?i) --> re.I/re.IGNORECASE

89 print(re.findall(r'(?i)yes', 'yes, Yes, YES')) #['yes, Yes, YES']

90 #(?m) --> re.M/re.MULTILINE: match multiline, ^ for head of line, $ for end of line

91 print(re.findall(r'(?im)^The|\w+e$', '''The first day, the last one,92 the great guy, the puppy love''')) #['The', 'the', 'love']

93 #(?s) --> re.S/re.DOTALL: dot(.) can be use to replace \n(default not)

94 print(re.findall(r'(?s)Th.+', '''This is the biggest suprise95 I'd ever seen''')) #['This is the biggest suprise\nI'd ever seen']

96 #(?x) --> re.X/re.VERBOSE: make re ignore the blanks and comments after '#' of re pattern

97 #This extension can make re pattern easy to read and you can add comments as you want

98 print(re.search(r'''(?x)99 \((\d{3})\) # Area code100 [ ] # blank101 (\d{3}) # prefix102 - # connecting line103 (\d{4}) # suffix104 ''', '(123) 456-7890').groups()) #['123', '456', '789']

105

106 #(?:...): make a sub group that no need to save and never use later

107 print(re.findall(r'(?:\w{3}\.)(\w+\.com)', 'www.google.com')) #['google.com']

108

109 #(?=...) and (?!...)

110 #(?=...): match the pattern which end with ..., pattern should place before (?=...)

111 print(re.findall(r'\d{3}(?=Start)', '222Start333, this is foo, 777End666')) #['222']

112 #(?!...): match the pattern which not end with ..., pattern should place before (?!...)

113 print(re.findall(r'\d{3}(?!End)', '222Start333, this is foo, 777End666')) #['222', '333', '666']

114

115 #(?<=...) and (?

116 #(?<=...): match the pattern which start with ..., pattern should place after (?<=...)

117 print(re.findall(r'(?<=Start)\d{3}', '222Start333, this is foo, 777End666')) #['333']

118 #(?

119 print(re.findall(r'(?

120

121 #(?(id/name)Y|X): if sub group \id or name exists, match Y, otherwise match X

122 #Below code first match the first char, if 'x' matched, store a sub group, if 'y', not to store

123 #then match second char, if sub group stored('x' matched), match 'y', otherwise match 'x', finally return result

124 print(re.search(r'(?:(x)|y)(?(1)y|x)', 'yx'))125

126 #Greedy match: '+' and '*' act greedy match, appending '?' to make no greedy match

127 print(re.search(r'.+(\d+-\d+-\d+)', 'asdfgh1234-123-123').group(1)) #4-123-123

128 print(re.search(r'.+?(\d+-\d+-\d+)', 'asdfgh1234-123-123').group(1)) #1234-123-123

129 print(re.search(r'.*(\d+-\d+-\d+)', 'asdfgh1234-123-123').group(1)) #4-123-123

130 print(re.search(r'.*?(\d+-\d+-\d+)', 'asdfgh1234-123-123').group(1)) #1234-123-123

131

132 #match and fullmatch

133 print(re.match(r'This is a full match', 'this is a full match string', re.I)) #this is a full match

134 print(re.fullmatch(r'This is a full match', 'this is a full match string', re.I)) #None

135

136 #span function

137 print(re.search(r'Google', 'www.google.com', re.I).span()) #(4, 10)

View Code

分段解释

导入re模块后,为方便后续使用,首先定义一个regexp方法,实现对re的正则表达式编译,输出,以及显示的功能。默认参数下,使用 search 方法进行匹配,并对匹配结果调用 group 函数,获取返回信息,可通过传入参数修改 regexp 的默认运行参数。

Note: 此处为方便后续使用而降低了代码的可读性。

1 importre2 """

3 Regular Expression4 """

5

6 def regexp(pattern, target, *args, grp='group', prt=True, func='search'):7 pat =re.compile(pattern)8 try:9 r = getattr(getattr(re, func)(pattern, target), grp)(*args)10 exceptAttributeError as e:11 r =None12 #print(e)

13 ifprt:14 print(r)15 return r

接下来利用上的 regexp 函数来完成后续的匹配工作,注释部分为输出结果。

使用“.”来匹配所有非“\n”的字符

1 #Use . to match all

2 print(30*'-')3 regexp('.+', 'exit soon\nHurry up.') #'exit soon'

使用“()”来生成匹配子组

1 #Use () to make sub-groups

2 print(30*'-')3 regexp('(.+) (.+)', 'exit soon', 1) #'exit'

4 regexp('(.+) (.+)', 'exit soon', 2) #'soon'

5 regexp('(.+) (.+)', 'exit soon', grp='groups') #('exit', 'soon')

使用“^”来表示从头部匹配(“$为尾部”)

1 #Use ^ to search from head

2 print(30*'-')3 regexp('^The', 'The End') #'The'

4 regexp('^The', 'In The End') #None

使用“\b”来匹配边界(空白符等)

1 #Use \b to search boundary

2 print(30*'-')3 regexp(r'\bThe\b', 'In The End') #'The'

4 regexp(r'\bThe', 'In TheEnd') #'The'

5 regexp(r'The\b', 'In TheEnd') #None

match和search函数的对比,区别在于匹配开始的位置

1 #match and search

2 print(30*'-')3 regexp('The', 'In The End', func='search') #'the'

4 regexp('The', 'In The End', func='match') #None

findall和finditer的对比,区别在于返回对象是列表还是迭代器

1 #findall and finditer

2 #Note:

3 #findall returns a list that contains string of matched result

4 #finditer returns a iterator that contains obj of matched result

5 #re.IGNORECASE can ignore capitalized

6 print(30*'-')7 print(re.findall('The', 'In The End, these things merged', re.I)) #['The', 'The']

8 itera = re.finditer('The', 'In The End, these things merged', re.I)9 for x initera:10 print(x.group()) #'The'

sub和subn的对比,区别在于返回对象中是否包含计数值

1 #sub and subn

2 print(re.sub('X', 'LIKE', 'This is X, X is acting'))3 print(re.subn('X', 'LIKE', 'This is X, X is acting'))

使用split函数切分目标字符串

1 #split: split(re-expression, string)

2 print(re.split(', |\n', 'This is amazing\nin the end, those things merged'))

使用\N来获取对应子组的匹配内容,(?P)来生成具名子组

1 #\N: use \N to represent sub group, N is the number of sub group

2 print(re.sub(r'(.{3})-(.{3})-(.{3})', r'\2-\3-\1', '123-def-789')) #'def-789-123'

3 #(?P): similar to \N, add tag name for each sub group,

4 #and use \g to fetch sub group

5 print(re.sub(r'(?P\d{3})-(?P\d{3})-(?P\d{3})', r'\g-\g-\g', '123-456-789')) #456-789-123

使用(?P=name)来调用具名子组的匹配内容

Note: 此处的(?P=name)需要与(?P)在同一个表达式模式内,且调用的是匹配结果而不是匹配模式。若需要在不同表达式中使用,可以利用\N或\g来获取子组的匹配结果。

1 #(?P=name): use this expression to reuse former sub group result

2 #Note: this expression only get the matched result, not the re pattern

3 print(re.match(r'(?P\d{3})-(?P\w{3})-(?P=char)-(?P=digit)', '123-abc-abc-123')) #Match obj, '123-abc-abc-123'

4 print(re.match(r'(?P\d{3})-(?P\w{3})-(?P=char)-(?P=digit)', '123-abc-def-456')) #None

5

6 #Note: should use (?P=name) in a re expression with former named group

7 print(re.sub(r'(?Ppotato)(XXX)(?P=myName)', r'YY\2YY', 'potatoXXXpotato')) #'YYXXXYY'

8 print(re.sub(r'(?P\d{3})-(?P\w{4})', r'(?P=char)-(?P=digit)', '123-abcd')) #failed:(?P=char)-(?P=digit)

9

10 print(re.sub(r'(?P\d{3})-(?P\w{4})', r'\2-\1', '123-abcd')) #'abcd-123'

11 print(re.sub(r'(?P\d{3})-(?P\w{4})', r'\g-\g', '123-abcd')) #'abcd-123'

使用groupdict()来获取匹配结果的字典

1 #groupdict(): return dict of named pattern

2 print(re.match(r'(?P\d{3})-(?P\w{4})', '123-abcd').groupdict()) #{'char': 'abcd', 'digit': '123'}

3 print(re.match(r'(?P\d{3})-(?P\w{4})', '123-abcd').group('char')) #'abcd'

4 print(re.match(r'(?P\d{3})-(?P\w{4})', '123-abcd').group('digit'))

re表达式的aimLsux标签的使用

1 #re extensions

2 #use (?aiLmsux): re.A, re.I, re.L, re.M, re.S, re.X

3 #use (?imsx)

4 #(?i) --> re.I/re.IGNORECASE

5 print(re.findall(r'(?i)yes', 'yes, Yes, YES')) #['yes, Yes, YES']

6 #(?m) --> re.M/re.MULTILINE: match multiline, ^ for head of line, $ for end of line

7 print(re.findall(r'(?im)^The|\w+e$', '''The first day, the last one,8 the great guy, the puppy love''')) #['The', 'the', 'love']

9 #(?s) --> re.S/re.DOTALL: dot(.) can be use to replace \n(default not)

10 print(re.findall(r'(?s)Th.+', '''This is the biggest suprise11 I'd ever seen''')) #['This is the biggest suprise\nI'd ever seen']

12 #(?x) --> re.X/re.VERBOSE: make re ignore the blanks and comments after '#' of re pattern

13 #This extension can make re pattern easy to read and you can add comments as you want

14 print(re.search(r'''(?x)15 \((\d{3})\) # Area code16 [ ] # blank17 (\d{3}) # prefix18 - # connecting line19 (\d{4}) # suffix20 ''', '(123) 456-7890').groups()) #['123', '456', '789']

使用(?:…)来生成一个无需保存复用的子组

1 #(?:...): make a sub group that no need to save and never use later

2 print(re.findall(r'(?:\w{3}\.)(\w+\.com)', 'www.google.com')) #['google.com']

使用正向肯定搜索和正向否定搜索

1 #(?=...) and (?!...)

2 #(?=...): match the pattern which end with ..., pattern should place before (?=...)

3 print(re.findall(r'\d{3}(?=Start)', '222Start333, this is foo, 777End666')) #['222']

4 #(?!...): match the pattern which not end with ..., pattern should place before (?!...)

5 print(re.findall(r'\d{3}(?!End)', '222Start333, this is foo, 777End666')) #['222', '333', '666']

使用反向肯定搜索和反向否定搜索

1 #(?<=...) and (?

2 #(?<=...): match the pattern which start with ..., pattern should place after (?<=...)

3 print(re.findall(r'(?<=Start)\d{3}', '222Start333, this is foo, 777End666')) #['333']

4 #(?

5 print(re.findall(r'(?

使用条件选择匹配

1 #(?(id/name)Y|X): if sub group \id or name exists, match Y, otherwise match X

2 #Below code first match the first char, if 'x' matched, store a sub group, if 'y', not to store

3 #then match second char, if sub group stored('x' matched), match 'y', otherwise match 'x', finally return result

4 print(re.search(r'(?:(x)|y)(?(1)y|x)', 'yx'))

贪婪匹配与非贪婪匹配

1 #Greedy match: '+' and '*' act greedy match, appending '?' to make no greedy match

2 print(re.search(r'.+(\d+-\d+-\d+)', 'asdfgh1234-123-123').group(1)) #4-123-123

3 print(re.search(r'.+?(\d+-\d+-\d+)', 'asdfgh1234-123-123').group(1)) #1234-123-123

4 print(re.search(r'.*(\d+-\d+-\d+)', 'asdfgh1234-123-123').group(1)) #4-123-123

5 print(re.search(r'.*?(\d+-\d+-\d+)', 'asdfgh1234-123-123').group(1)) #1234-123-123

完全匹配与非完全匹配

1 #match and fullmatch

2 print(re.match(r'This is a full match', 'this is a full match string', re.I)) #this is a full match

3 print(re.fullmatch(r'This is a full match', 'this is a full match string', re.I)) #None

span()函数查看匹配位置

1 #span function

2 print(re.search(r'Google', 'www.google.com', re.I).span()) #(4, 10)

3.2函数替换实例

介绍一个替换实例,利用函数/匿名函数来代替替换对象,

首先赋值被匹配对象,定义double函数,该函数会获取子组并将其乘2后返回字符串,利用sub函数的repl参数传入double函数,进行匹配替换,同样可以使用lambda函数进行实现。

Note: 当sub的repl是一个函数时,该函数需接受一个参数,该参数为匹配结果的返回实例。

1 importre2

3 s = 'AD892SDA213VC2'

4

5 defdouble(matched):6 value = int(matched.group('value'))7 return str(value*2)8 print(re.sub(r'(?P\d+)', double, s))9

10 print(re.sub(r'(?P\d+)', lambda x: str(int(x.group('value'))*2), s))11

12 #Output: 'AD1784SDA426VC4'

python正则表达式匹配模式_Python与正则表达式[0] - re 模块的正则表达式匹配相关推荐

  1. python 全中文匹配字符_Python教程:进程和线程amp;正则表达式

    字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在.比如判断一个字符串是否是合法的Email地址,虽然可以编程提取@前后的子串,再分别判断是否是单词和域名,但这样做不但麻烦, ...

  2. python的out模式_Python设计模式之状态模式

    状态模式 面向对象编程着力于在对象交互时改变它们的状态.在很多问题中,有限状态机(通常名为状态机)是一个非常方便的状态转换建模(并在必要时以数学方式形式化)工具.首先,什么是状态机?状态机是一个抽象机 ...

  3. python随机生成数字_Python 中生成 0 到 9 之间的随机整数

    很少有Python示例向您展示如何生成0(含)和9(含)之间的随机整数0 1 2 3 4 5 6 7 8 9 1.randrange 1.1生成0到9之间的随机整数 #!/usr/bin/python ...

  4. python爬虫提取人名_python爬虫—爬取英文名以及正则表达式的介绍

    python爬虫-爬取英文名以及正则表达式的介绍 爬取英文名: 一. 爬虫模块详细设计 (1)整体思路 对于本次爬取英文名数据的爬虫实现,我的思路是先将A-Z所有英文名的连接爬取出来,保存在一个csv ...

  5. python简单工厂模式_python版简单工厂模式

    什么是简单工厂模式 工厂模式有一种非常形象的描述,建立对象的类就如一个工厂,而需要被建立的对象就是一个个产品:在工厂中加工产品,使用产品的人,不用在乎产品是如何生产出来的.从软件开发的角度来说,这样就 ...

  6. python读取文件模式_python如何读取文件的数据

    使用 read() 函数读取文件时,如果文件过大,则一次读取全部内容到内存,容易造成内存不足,而相比每次限制读取字符(或字节)的个数,更推荐大家使用逐行读取文件的方式.一般情况下,逐行读取只适用于以文 ...

  7. python selenium po模式_Python+Selenium+Unittest实现PO模式web自动化框架

    1)效率高 :PO模式的逻辑层方法有具体定义,元素发生变化修改逻辑层,业务层不变.这样看来结构简单清晰,舒服更符合人类习惯, 普通方式就是继续堆case. 2) 复用多收益大: 同样这里如果逻辑复用越 ...

  8. python抽象工厂模式_Python设计模式之抽象工厂模式

    Python设计模式之抽象工厂模式 这篇文章主要为大家详细介绍了Python设计模式之抽象工厂模式,感兴趣的小伙伴们可以参考一下 python面向对象编程入门,我们需要不断学习进步 "&qu ...

  9. python 享元模式_python 设计模式之享元(Flyweight)模式

    #写在前面 这个设计模式理解起来很容易.百度百科上说的有点绕口. #享元模式的定义 运用共享技术来有効地支持大量细粒度对象的复用. 它通过共享已经存在的对橡大幅度减少需要创建的对象数量.避免大量相似类 ...

最新文章

  1. etcd 笔记(01)— etcd 简介、特点、应用场景、常用术语、分布式 CAP 理论、分布式原理
  2. gitlab报错 fatal: index-pack failed error: RPC failed; result=18, HTTP code = 200解决方案
  3. 锁死AI基础研究的两个「智子」是什么?
  4. python中的列表操作
  5. HDU 3613 Best Reward 正反两次扩展KMP
  6. Linux下生成指定大小文件(命令+Java程序)
  7. syslog 向内存中缓存_动画:深入浅出从根上理解 HTTP 缓存机制及原理!
  8. Codeforces 827D Best Edge Weight 倍增 + 并查集 || 倍增 + 压倍增标记 (看题解)
  9. 进入快速通道的委托(深入理解c#)
  10. java使用org.w3c.dom解析XML文档,创建、增删查改,保存,读取,遍历元素等操作
  11. Open Inventor与Coin3D开发环境配置/Vs2017+Qt+coin3D配置方法,实测可用
  12. Oracle dmp文件结构探秘
  13. 前端程序员《HTML》学习笔记(3)之标签学习
  14. SQL优化:使用distribute by 防止数据倾斜
  15. 【生存游戏】一组按序排列围成一圈的参赛选手,通过逢3退1游戏机制筛选出最后一个生存者的Java算法
  16. 群晖linux文件夹颜色红色,技术干货分享 | 群晖备份Linux文件夹~
  17. 从B站审核变慢现象,聊聊谛听安全内容社区产品的内容风控
  18. k8spod控制器概述
  19. ID号自动生成,补缺功能
  20. ddn高性能服务器,HPE牵手DDN打造整合的高性能服务器存储产品组合

热门文章

  1. 3星|《三联生活周刊》2017年41期:有些手术的疗效源于安慰剂效应
  2. Oracle之虚拟列及虚拟列索引
  3. Kali-Linux-2021.1 root登录
  4. 阿门,愿上帝保佑工作顺利
  5. MySQL批量更新数据总结
  6. Taro+NutUI+vue3+TypeScript - 图片上传
  7. 尚硅谷在线教育项目P132修改pom.xml等文件后依然报错not found
  8. 低功耗之产品功耗计算
  9. UVA 12086 (树状数组)
  10. 有效市场假设与量化投资