python 正则表达式
Python 中一类主要的处理对象就是字符串,如何从字符串中筛选特定模式的子字符串就需要正则表达式。使用正则表达式的模式和字符串既可以是 Unicode 字符串(str),也可以是 8 为字节串(bytes)。本节介绍如何在 Python 中使用正则表达式。
正则表达式调用格式
python
1 | import re |
其中,re 是 python 内置的正则表达式模块,r’xxx’ 为匹配模式,flags 为一个可选参数,称为标记,可配置为是否忽略大小写(re.I)、采用多行模式(re.M)等。re.compile 为将匹配模式编译为正则表达式,会被缓存。match, findall 等编译后的正则表达式对象支持的方法和属性(如 re_exp.flags, re_exp.groups, re_exp.pattern等)。
正则表达式语法-匹配模式
正则表达式中有一些特殊语法,具体的如下:
- 绝大部分普通字符(如 ‘A’, ‘a’, ‘0’ 等)是最简单的表达式,匹配自身;除此之外,还有一些特殊字符。
.
默认模式下匹配除了换行以外的任意字符;如py.
可匹配 ‘pyc’, ‘pyo’, ‘py!’^
匹配字符串的开头;$
匹配字符串的结尾;*
对它前面的正则式匹配 0 到任意次重复,尽量多的匹配字符串,即贪婪匹配;+
对它前面的正则式匹配 1 到任意次重复;?
对它前面的正则式匹配 0 到 1 次重复;*?, +?, ??
因为*, +, ?
都是贪婪匹配,它们会进行尽可能多的匹配。但有时不需要这种行为,在它们末尾再增加?
则转变为非贪婪方式,会尽量少的进行字符匹配;{m}
对其前面的正则式指定匹配 个重复,如果少于 个则会导致匹配失败;{m,n}
对其前面的正则式进行 到 次匹配,属于贪婪式,会在 和 之间取尽量多。忽略 意指 ,忽略 意指 取无穷大。特别注意逗号不能省略,否则无法辨识修饰符应该忽略哪个边界;{m,n}?
采用非贪婪模式,只匹配 和 之间尽量少的字符次数;\
转义字符(允许你匹配上面出现的特殊字符);[]
表示在中括号里的字符为字符串中出现的可选字符。只匹配中括号中出现的字符。如[a-f0-9A-F]
匹配十六进制位、[0-5][0-9]
匹配 00 到 59 时间数。如果特殊字符出现在中括号中,则将使特殊字符失去特殊含义,功能同转义字符。[^5]
匹配除了5以外的字符;如果要匹配]
,可以采用:1)前面增加转义字符[()\]]
;2)放在首位[]()]
,其中()
为其他需要匹配的字符;|
或符号,如A|B
则正则式A
或B
;()
表示将匹配完成的内容截取除小括号中的内容;\A
只匹配字符串开始;\b
匹配空字符串,但只能在单词开始或结尾的位置;\B
匹配空字符串,但不能在单词的开始或结尾的位置,如r'py\B'
匹配 ‘python’, ‘py3’,但不匹配 ‘py’;\d
匹配十进制数;如00\d
可匹配 ‘007’,但无法匹配 ‘00A’\D
匹配非十进制数;\s
匹配空白字符;\S
匹配非空白字符;\w
匹配词语字符,包含构成词语的绝对部分字符,也包括数字和下划线;如\w\w\d
可匹配 ‘py3’\W
匹配非单词字符的字符;\Z
只匹配字符串尾;
正则表达式 flags 标记
re.A
或re.ASCII
让\w, \W, \b, \B, \d, \D, \s, \S
只匹配 ASCII,而不是 Unicode;re.DEBUG
显示编译时的 debug 信息;re.I
或re.IGNORECASE
忽略大小写匹配;如模式[A-Z]
也只会匹配小写字符;re.L
或re.LOCALE
由当前语言区域决定\w, \W, \b, \B
和大小写敏感匹配;re.M
或re.MULTILINE
样式字符^
匹配字符串的开始,和每一行的开始(换行符后面紧跟的符号)、样式字符$
匹配字符串尾,和每一行的结尾(换行符前面那个符号)。注意,默认情况下^
只匹配字符串开头,$
只匹配字符串结尾;re.S
或re.DOTALL
让.
匹配换行符,默认情况下,.
只匹配除了换行符以外的其他任意字符;re.X
或re.VERBOSE
这个标记允许你编写更具可读性更友好的正则表达式。通过分段和添加注释。
正则表达式函数
re.search(pattern, string, flags=0)
扫描整个 字符串 string 找到匹配样式的第一个位置,并返回一个相应的匹配对象。如果没有匹配,就返回一个None
; 注意这和找到一个零长度匹配是不同的;re.match(pattern, string, flags=0)
只从 string 的开始匹配到了正则表达式样式,就返回一个相应的匹配对象 。 如果没有匹配,就返回None
;注意它跟零长度匹配是不同的。注意即便是MULTILINE
多行模式,re.match()
也只匹配字符串的开始位置,而不匹配每行开始。如果你想定位 string 的任何位置,使用search()
来替代;re.fullmatch(pattern, string, flags=0)
如果整个 string 匹配到正则表达式样式,就返回一个相应的 匹配对象 。 否则就返回一个None
;注意这跟零长度匹配是不同的;re.split(pattern, string, maxsplit=0, flags=0)
用 pattern 分开 string。如果在 pattern 中捕获到括号,那么所有的组里的文字也会包含在列表里。如果 maxsplit 非零, 最多进行 maxsplit 次分隔, 剩下的字符全部返回到列表的最后一个元素;re.findall(pattern, string, flags=0)
以列表形式返回所有匹配到的子字符串;re.finditer(pattern, string, flags=0)
pattern 在 string 里所有的非重复匹配,返回为一个迭代器 iterator 保存了匹配对象。 string 从左到右扫描,匹配按顺序排列。空匹配也包含在结果里;re.sub(pattern, repl, string, count=0, flags=0)
返回通过使用 repl 替换在 string 最左边非重叠出现的 pattern 而获得的字符串。 如果样式没有找到,则不加改变地返回 string。 repl 可以是字符串或函数;如为字符串,则其中任何反斜杠转义序列都会被处理;re.subn(pattern, repl, string, count=0, flags=0)
行为与sub()
相同,但是返回一个元组(字符串, 替换次数)
;re.escape(pattern)
转义 pattern 中的特殊字符。如果你想对任意可能包含正则表达式元字符的文本字符串进行匹配,它就是有用的;re.purge()
清除正则表达式的缓存。
示例
[a-zA-Z\_][0-9a-zA-Z\_]*
可以匹配由字母或下划线开头,后接任意个由一个数字、字母或者下划线组成的字符串,也就是 Python 合法的变量;A|B
可以匹配 A 或 B,所以(P|p)ython
可以匹配 ‘Python’ 或者 ‘python’;^\d
表示必须以数字开头;\d$
表示必须以数字结束;
python
1 | re.split(r'\s+', 'a b c') |
python
1 | re.split(r'[\s\,]+', 'a,b, c d') |
python
1 | re.split(r'[\s\,\;]+', 'a,b;; c d') |
python
1 | re.findall(r"(\w+)=(\d+)", "set width=20 and height=10") |
python
1 | # 替换,下面例子将 / 替换为 - |
参考文献
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 J. Xu!
评论