python正则表达式
在编程中使用字符串操作的场景非常多,基本的python提供字符串处理方法包括
print(dir(str))
[..........'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']可以在devdocs或者dash查询每个方法的具体使用情况,使用较多的包含
format格式化字符串使用isalnum判断是否仅由字母和数字组成isalpha判断是否仅由字母组成isdecimal判断是否仅由数字组成isspace判断是否仅由空格组成replace部分字符串的替换split分割字符串strip去掉空格或者其他字符串
可以使用这些函数对字符串进行一系列的操作,来得到我们想要的字符串变化的结果。
如果需要对字符串做更复杂的一些匹配或者替换操作,我们可以使用正则表达式来更方便的执行。
正则表达式
正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE),又称正規表示式、正規表示法、規則運算式、常規表示法,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器裡,正則表达式通常被用来检索、替换那些符合某个模式的文本。 wikipedia
正则表达式基本语法
特殊字符是:
.(点) 在默认模式,匹配除了换行的任意字符。如果指定了标签
DOTALL,它将匹配包括换行符的任意字符。^(插入符号) 匹配字符串的开头, 并且在
MULTILINE模式也匹配换行后的首个符号。*对它前面的正则式匹配0到任意次重复, 尽量多的匹配字符串。
ab*会匹配'a','ab', 或者'a'``后面跟随任意个 ``'b'。+对它前面的正则式匹配1到任意次重复。
ab+会匹配'a'后面跟随1个以上到任意个'b',它不会匹配'a'。?对它前面的正则式匹配0到1次重复。
ab?会匹配'a'或者'ab'。*?,+?,??'*','+',和'?'修饰符都是 贪婪的;它们在字符串进行尽可能多的匹配。有时候并不需要这种行为。如果正则式<.*>希望找到'<a> b <c>',它将会匹配整个字符串,而不仅是'<a>'。在修饰符之后添加?将使样式以 非贪婪方式或者 :dfn:最小 方式进行匹配; 尽量 少 的字符将会被匹配。 使用正则式<.*?>将会仅仅匹配'<a>'。"{m}"
对其之前的正则式指定匹配 m 个重复;少于 m 的话就会导致匹配失败。比如,
a{6}将匹配6个'a', 但是不能是5个。"{m, n}"
对正则式进行 m 到 n 次匹配,在 m 和 n 之间取尽量多。 比如,
a{3,5}将匹配 3 到 5个'a'。忽略 m 意为指定下界为0,忽略 n 指定上界为无限次。 比如a{4,}b将匹配'aaaab'或者1000个'a'尾随一个'b',但不能匹配'aaab'。逗号不能省略,否则无法辨别修饰符应该忽略哪个边界。{m,n}?前一个修饰符的非贪婪模式,只匹配尽量少的字符次数。比如,对于
'aaaaaa',a{3,5}匹配 5个'a',而a{3,5}?只匹配3个'a'。\转义特殊字符(允许你匹配
'*','?', 或者此类其他),或者表示一个特殊序列;特殊序列之后进行讨论。如果你没有使用原始字符串(r'raw')来表达样式,要牢记Python也使用反斜杠作为转义序列;如果转义序列不被Python的分析器识别,反斜杠和字符才能出现在字符串中。如果Python可以识别这个序列,那么反斜杠就应该重复两次。这将导致理解障碍,所以高度推荐,就算是最简单的表达式,也要使用原始字符串。[]用于表示一个字符集合。在一个集合中:字符可以单独列出,比如
[amk]匹配'a','m', 或者'k'。可以表示字符范围,通过用'-'将两个字符连起来。比如[a-z]将匹配任何小写ASCII字符,[0-5][0-9]将匹配从00到59的两位数字,[0-9A-Fa-f]将匹配任何十六进制数位。 如果-进行了转义 (比如[a\-z])或者它的位置在首位或者末尾(如[-a]或[a-]),它就只表示普通字符'-'。特殊字符在集合中,失去它的特殊含义。比如[(+*)]只会匹配这几个文法字符'(','+','*', or')'。字符类如\w或者\S(如下定义) 在集合内可以接受,它们可以匹配的字符由ASCII或者LOCALE模式决定。不在集合范围内的字符可以通过 取反 来进行匹配。如果集合首字符是'^',所有 不 在集合内的字符将会被匹配,比如[^5]将匹配所有字符,除了'5',[^^]将匹配所有字符,除了'^'.^如果不在集合首位,就没有特殊含义。在集合内要匹配一个字符']',有两种方法,要么就在它之前加上反斜杠,要么就把它放到集合首位。比如,[()[\]{}]和[]()[{}]都可以匹配括号。Unicode Technical Standard #18 里的嵌套集合和集合操作支持可能在未来添加。这将会改变语法,所以为了帮助这个改变,一个FutureWarning将会在有多义的情况里被raise,包含以下几种情况,集合由'['开始,或者包含下列字符序列'--','&&','~~', 和'||'。为了避免警告,需要将它们用反斜杠转义。在 3.7 版更改: 如果一个字符串构建的语义在未来会改变的话,一个FutureWarning会raise。|A|B, A 和 B 可以是任意正则表达式,创建一个正则表达式,匹配 A 或者 B. 任意个正则表达式可以用'|'连接。它也可以在组合(见下列)内使用。扫描目标字符串时,'|'分隔开的正则样式从左到右进行匹配。当一个样式完全匹配时,这个分支就被接受。意思就是,一旦 A 匹配成功, B 就不再进行匹配,即便它能产生一个更好的匹配。或者说,'|'操作符绝不贪婪。 如果要匹配'|'字符,使用\|, 或者把它包含在字符集里,比如[|].(...)(组合),匹配括号内的任意正则表达式,并标识出组合的开始和结尾。匹配完成后,组合的内容可以被获取,并可以在之后用
\number转义序列进行再次匹配,之后进行详细说明。要匹配字符'('或者')', 用\(或\), 或者把它们包含在字符集合里:[(],[)].
由 '\' 和一个字符组成的特殊序列在以下列出。 如果普通字符不是ASCII数位或者ASCII字母,那么正则样式将匹配第二个字符。比如,\$ 匹配字符 '$'.
\number匹配数字代表的组合。每个括号是一个组合,组合从1开始编号。比如
(.+) \1匹配'the the'或者'55 55', 但不会匹配'thethe'(注意组合后面的空格)。这个特殊序列只能用于匹配前面99个组合。如果 number 的第一个数位是0, 或者 number 是三个八进制数,它将不会被看作是一个组合,而是八进制的数字值。在'['和']'字符集合内,任何数字转义都被看作是字符。\A只匹配字符串开始。
\d对于 Unicode (str) 样式:匹配任何Unicode十进制数(就是在Unicode字符目录[Nd]里的字符)。这包括了
[0-9],和很多其他的数字字符。如果设置了ASCII标志,就只匹配[0-9]。对于8位(bytes)样式:匹配任何十进制数,就是[0-9]。\D匹配任何非十进制数字的字符。就是
\d取非。 如果设置了ASCII标志,就相当于[^0-9]。\s对于 Unicode (str) 样式:匹配任何Unicode空白字符(包括
[ \t\n\r\f\v],还有很多其他字符,比如不同语言排版规则约定的不换行空格)。如果ASCII被设置,就只匹配[ \t\n\r\f\v]。对于8位(bytes)样式:匹配ASCII中的空白字符,就是[ \t\n\r\f\v]。\S匹配任何非空白字符。就是
\s取非。如果设置了ASCII标志,就相当于[^ \t\n\r\f\v]。\Z只匹配字符串尾。
绝大部分Python的标准转义字符也被正则表达式分析器支持。:
\a \b \f \n
\r \t \u \U
\v \x \\(注意 \b 被用于表示词语的边界,它只在字符集合内表示退格,比如 [\b] 。)
'\u' 和 '\U' 转义序列只在 Unicode 样式中支持。 在 bytes 算啊看会显示错误。 未知的 ASCII 字符转义序列保留在未来使用,会被当作错误来处理。
八进制转义包含为一个有限形式。如果首位数字是 0, 或者有三个八进制数位,那么就认为它是八进制转义。其他的情况,就看作是组引用。对于字符串文本,八进制转义最多有三个数位长。
在 3.3 版更改: 增加了 '\u' 和 '\U' 转义序列。
在 3.6 版更改: 由 '\' 和一个ASCII字符组成的未知转义会被看成错误。
python正则表达式 re模块
re.``compile(pattern, flags=0)将正则表达式的样式编译为一个 正则表达式对象 (正则对象),可以用于匹配,通过这个对象的方法
match(),search()以及其他如下描述。这个表达式的行为可以通过指定 标记 的值来改变。值可以是以下任意变量,可以通过位的OR操作来结合(|操作符)。序列prog = re.compile(pattern) result = prog.match(string)等价于result = re.match(pattern, string)如果需要多次使用这个正则表达式的话,使用re.compile()和保存这个正则对象以便复用,可以让程序更加高效。注解 通过re.compile()编译后的样式,和模块级的函数会被缓存, 所以少数的正则表达式使用无需考虑编译的问题。re.``search(pattern, string, flags=0)扫描整个 字符串 找到匹配样式的第一个位置,并返回一个相应的 匹配对象。如果没有匹配,就返回一个
None; 注意这和找到一个零长度匹配是不同的。re.``match(pattern, string, flags=0)如果 string 开始的0或者多个字符匹配到了正则表达式样式,就返回一个相应的 匹配对象 。 如果没有匹配,就返回
None;注意它跟零长度匹配是不同的。注意即便是MULTILINE多行模式,re.match()也只匹配字符串的开始位置,而不匹配每行开始。如果你想定位 string 的任何位置,使用search()来替代(也可参考 search() vs. match() )re.``fullmatch(pattern, string, flags=0)如果整个 string 匹配到正则表达式样式,就返回一个相应的 匹配对象 。 否则就返回一个
None;注意这跟零长度匹配是不同的。3.4 新版功能.re.``split(pattern, string, maxsplit=0, flags=0)用 pattern 分开 string 。 如果在 pattern 中捕获到括号,那么所有的组里的文字也会包含在列表里。如果 maxsplit 非零, 最多进行 maxsplit 次分隔, 剩下的字符全部返回到列表的最后一个元素。>>>
>>> re.split(r'\W+', 'Words, words, words.') ['Words', 'words', 'words', ''] >>> re.split(r'(\W+)', 'Words, words, words.') ['Words', ', ', 'words', ', ', 'words', '.', ''] >>> re.split(r'\W+', 'Words, words, words.', 1) ['Words', 'words, words.'] >>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE) ['0', '3', '9']如果分隔符里有捕获组合,并且匹配到字符串的开始,那么结果将会以一个空字符串开始。对于结尾也是一样>>>>>> re.split(r'(\W+)', '...words, words...') ['', '...', 'words', ', ', 'words', '...', '']这样的话,分隔组将会出现在结果列表中同样的位置。样式的空匹配将分开字符串,但只在不相临的状况生效。>>> re.split(r'\b', 'Words, words, words.') ['', 'Words', ', ', 'words', ', ', 'words', '.'] >>> re.split(r'\W*', '...words...') ['', '', 'w', 'o', 'r', 'd', 's', '', ''] >>> re.split(r'(\W*)', '...words...') ['', '...', '', '', 'w', '', 'o', '', 'r', '', 'd', '', 's', '...', '', '', '']在 3.1 版更改: 增加了可选标记参数。在 3.7 版更改: 增加了空字符串的样式分隔。re.``findall(pattern, string, flags=0)对 string 返回一个不重复的 pattern 的匹配列表, string 从左到右进行扫描,匹配按找到的顺序返回。如果样式里存在一到多个组,就返回一个组合列表;就是一个元组的列表(如果样式里有超过一个组合的话)。空匹配也会包含在结果里。在 3.7 版更改: 非空匹配现在可以在前一个空匹配之后出现了。
re.``sub(pattern, repl, string, count=0, flags=0)返回通过使用 repl 替换在 string 最左边非重叠出现的 pattern 而获得的字符串。 如果样式没有找到,则不加改变地返回 string。 repl 可以是字符串或函数;如为字符串,则其中任何反斜杠转义序列都会被处理。 也就是说,
\n会被转换为一个换行符,\r会被转换为一个回车附,依此类推。 未知的 ASCII 字符转义序列保留在未来使用,会被当作错误来处理。 其他未知转义序列例如\&会保持原样。 向后引用像是\6会用样式中第 6 组所匹配到的子字符串来替换。 例如:>>>>>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):', ... r'static PyObject*\npy_\1(void)\n{', ... 'def myfunc():') 'static PyObject*\npy_myfunc(void)\n{'如果 repl 是一个函数,那它会对每个非重复的 pattern 的情况调用。这个函数只能有一个 匹配对象 参数,并返回一个替换后的字符串。比如>>>>>> def dashrepl(matchobj): ... if matchobj.group(0) == '-': return ' ' ... else: return '-' >>> re.sub('-{1,2}', dashrepl, 'pro----gram-files') 'pro--gram files' >>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE) 'Baked Beans & Spam'样式可以是一个字符串或者一个 样式对象 。可选参数 count 是要替换的最大次数;count 必须是非负整数。如果忽略这个参数,或者设置为0,所有的匹配都会被替换。空匹配只在不相临连续的情况被更替,所以sub('x*', '-', 'abxd')返回'-a-b--d-'。在字符串类型的 repl 参数里,如上所述的转义和向后引用中,\g<name>会使用命名组合name,(在(?P<name>…)语法中定义)\g<number>会使用数字组;\g<2>就是\2,但它避免了二义性,如\g<2>0。\20就会被解释为组20,而不是组2后面跟随一个字符'0'。向后引用\g<0>把 pattern 作为一整个组进行引用。在 3.1 版更改: 增加了可选标记参数。在 3.5 版更改: 不匹配的组合替换为空字符串。在 3.6 版更改: pattern 中的未知转义(由'\'和一个 ASCII 字符组成)被视为错误。在 3.7 版更改: repl 中的未知转义(由'\'和一个 ASCII 字符组成)被视为错误。在 3.7 版更改: 样式中的空匹配相邻接时会被替换。re.``subn(pattern, repl, string, count=0, flags=0)行为与
sub()相同,但是返回一个元组(字符串, 替换次数).在 3.1 版更改: 增加了可选标记参数。在 3.5 版更改: 不匹配的组合替换为空字符串。re.``escape(pattern)转义 pattern 中的特殊字符。如果你想对任意可能包含正则表达式元字符的文本字符串进行匹配,它就是有用的。比如>>>
>>> print(re.escape('python.exe')) python\.exe >>> legal_chars = string.ascii_lowercase + string.digits + "!#$%&'*+-.^_|~:" >>> print('[%s]+' % re.escape(legalchars)) [abcdefghijklmnopqrstuvwxyz0123456789!#$%\&'*+-.\^\|\~:]+ >>> operators = ['+', '-', '*', '/', '**'] >>> print('|'.join(map(re.escape, sorted(operators, reverse=True)))) /|\-|\+|\*\*|\*这个函数不能用在sub()和subn()的替换字符串里,只有反斜杠应该被转义,比如说>>>>>> digits_re = r'\d+' >>> sample = '/usr/sbin/sendmail - 0 errors, 12 warnings' >>> print(re.sub(digits_re, digits_re.replace('\\', r'\\'), sample)) /usr/sbin/sendmail - \d+ errors, \d+ warnings在 3.3 版更改:'_'不再被转义。在 3.7 版更改: 只有在正则表达式中可以产生特殊含义的字符会被转义。re.``purge()清除正则表达式缓存。
exception
re.``error(msg, pattern=None, pos=None)raise一个例外。当传递到函数的字符串不是一个有效正则表达式的时候(比如,包含一个不匹配的括号)或者其他错误在编译时或匹配时产生。如果字符串不包含样式匹配,是不会被视为错误的。错误实例有以下附加属性:msg未格式化的错误消息。pattern正则表达式样式。pos编译失败的 pattern 的位置索引(可以是None)。lineno对应 pos (可以是None) 的行号。colno对应 pos (可以是None) 的列号。在 3.5 版更改: 添加了附加属性。python正则表达式 正则对象
编译后的正则表达式对象支持一下方法和属性:
Pattern.``search(string[, pos[, endpos]])扫描整个 string 寻找第一个匹配的位置, 并返回一个相应的 匹配对象。如果没有匹配,就返回
None;注意它和零长度匹配是不同的。可选的第二个参数 pos 给出了字符串中开始搜索的位置索引;默认为0,它不完全等价于字符串切片;'^'样式字符匹配字符串真正的开头,和换行符后面的第一个字符,但不会匹配索引规定开始的位置。可选参数 endpos 限定了字符串搜索的结束;它假定字符串长度到 endpos , 所以只有从pos到endpos - 1的字符会被匹配。如果 endpos 小于 pos,就不会有匹配产生;另外,如果 rx 是一个编译后的正则对象,rx.search(string, 0, 50)等价于rx.search(string[:50], 0)。>>>>>> pattern = re.compile("d") >>> pattern.search("dog") # Match at index 0 <re.Match object; span=(0, 1), match='d'> >>> pattern.search("dog", 1) # No match; search doesn't include the "d"Pattern.``match(string[, pos[, endpos]])如果 string 的 开始位置 能够找到这个正则样式的任意个匹配,就返回一个相应的 匹配对象。如果不匹配,就返回
None;注意它与零长度匹配是不同的。可选参数 pos 和 endpos 与search()含义相同。>>>>>> pattern = re.compile("o") >>> pattern.match("dog") # No match as "o" is not at the start of "dog". >>> pattern.match("dog", 1) # Match as "o" is the 2nd character of "dog". <re.Match object; span=(1, 2), match='o'>如果你想定位匹配在 string 中的位置,使用search()来替代(另参考 search() vs. match())。Pattern.``fullmatch(string[, pos[, endpos]])如果整个 string 匹配这个正则表达式,就返回一个相应的 匹配对象 。 否则就返回
None; 注意跟零长度匹配是不同的。可选参数 pos 和 endpos 与search()含义相同。>>>>>> pattern = re.compile("o[gh]") >>> pattern.fullmatch("dog") # No match as "o" is not at the start of "dog". >>> pattern.fullmatch("ogre") # No match as not the full string matches. >>> pattern.fullmatch("doggie", 1, 3) # Matches within given limits. <re.Match object; span=(1, 3), match='og'>3.4 新版功能.Pattern.``split(string, maxsplit=0)等价于
split()函数,使用了编译后的样式。Pattern.``finditer(string[, pos[, endpos]])类似函数
finiter(), 使用了编译后样式,但也可以接收可选参数 pos 和 endpos ,限制搜索范围,就像search()。Pattern.``sub(repl, string, count=0)等价于
sub()函数,使用了编译后的样式。Pattern.``subn(repl, string, count=0)等价于
subn()函数,使用了编译后的样式。Pattern.``flags正则匹配标记。这是可以传递给
compile()的参数,任何(?…)内联标记,隐性标记比如UNICODE的结合。Pattern.``groups捕获组合的数量。
Pattern.``groupindex映射由
(?P<id>)定义的命名符号组合和数字组合的字典。如果没有符号组,那字典就是空的。Pattern.``pattern编译对象的原始样式字符串。
在 3.7 版更改: 添加 copy.copy() 和 copy.deepcopy() 函数的支持。编译后的正则表达式对象被认为是原子性的。
Last updated
Was this helpful?