Python 正则

python 正则表达式,导入re模块。

正则表达式可视化 对正则表达式进行解释

转义字符

转义字符 含义
\A 只匹配字符串开始。
\b 匹配单词的词首和词尾,r'\bclass\b'
\B 匹配空字符串,但不能在词的开头或者结尾
\d 匹配数字
\D 匹配任何非十进制数字的字符
\s 匹配[ \t\n\r\f\v]等空白符
\S 匹配任何非空白字符
\w 匹配数字或字母[a-zA-Z0-9_]
\W 匹配任何不是单词字符的字符。 这与 正相反。[^a-zA-Z0-9_]
\Z 只匹配字符串尾
. 匹配一个字符
[0-9a-zA-Z\_] 匹配一个数字、字母或者下划线
* 匹配0个或多个字符
+ 匹配1个或多个字符
? 匹配0个或1个字符;非贪婪匹配,即尽可能少匹配
{n} 匹配n个字符
{n,m} 匹配n-m个字符
A\|B 匹配A或B
^ 表示行的开头 等同\A
$ 表示行的结束 等同\Z
() 表示分组

re函数

re函数 含义
re.match() 方法判断是否匹配,如果匹配成功,返回一个Match对象,否则返回None。
re.match(r'','').groups(default=None) 返回一个元组,包含所有匹配的子组,在样式中出现的从1到任意多的组合。 default 参数用于不参与匹配的情况,默认为 None。
re.match(r'','').group([n]) 返回被 RE 匹配的字符串,默认n为0,等同re.match(r'','')[0]
re.match(r'','').start() 返回匹配开始的位置
re.match(r'','').end() 返回匹配结束的位置
re.match(r'','').span() 返回一个元组包含匹配 [开始,结束) 的位置
re.search(r'','')
re.split(r'\s+', 'a b c') 切分字符串
re.compile(r'') 预编译正则表达式
re.findall(r'','') 将所有匹配的结果作为元组组成列表
re.finditer(r'','') 将所有匹配的结果作为迭代器返回
re.sub(r'', A, B, n)) 把B字符串中的匹配项替换成A字符串,匹配n次,默认为0即全部替换

编译标志

编译标志 含义
re.S / [DOTALL] 使 . 匹配包括换行在内的所有字符
re.I / [IGNORECASE] 使匹配对大小写不敏感
re.M / [MULTILINE] 多行匹配,影响 ^$
re.L / [LOCALE] 做本地化识别(locale-aware)匹配
re.X / [VERBOSE] 更清晰地组织和缩进 RE,允许将注释"#"写入 RE,该符号不能在字符串或反斜杠之后

高级用法--?的使用

(?...) 含义
(?aiLmsux) 正则表达式内的编译标志,
例子: re.match(r'(?i)(ab)c','aBc').group(1)
(?:...) 正则括号的非捕获版本,可理解为忽略该分组,
例子: re.match(r'(?i:aB)','aB00').groups()
(?P<name>...) 命名组合,引用组合的方式
1.正则式 (?P=name) 《==》\1 。比如 (?P<name>['"]).*?(?P=name)
2.处理匹配对象m, m.group('name')
3.传递到 re.sub() 里的 repl 参数中, \g<quote> 《==》 \g<1> 《==》 \1
(?P=name) 反向引用一个命名组合;
它匹配前面那个叫 name 的命名组中匹配到的串同样的字串。
(?#...) 注释;里面的内容会被忽略。
(?=...) 前瞻性断言,匹配时的判断条件,
比如 hello (?=world) 只有在后面是 'world' 的时候匹配 'hello '
(?!...) 否定超前断言,前视取反,
比如 hello (?!world) 只有在后面不是 'world' 的时候匹配 'hello '
(?<=...) 肯定断言,正向后视断定
(?<!...) 否定后视断言,后视断定取非,
(?(id/name)yes-pattern\|no-pattern) 判断 idname 存在。
比如, (<)?(\w+@\w+(?:\.\w+)+)(?(1)>\|$) 是一个email样式匹配

练习题

来源:廖雪峰的python教程

验证Email地址的正则表达式,

  • someone@gmail.com
  • bill.gates@microsoft.com
  • <someone@gmail.com>
代码参考
# coding:utf-8 # re 模块 import re def is_valid_email(addr): m = re.match(r'^[\w\.]+@[a-zA-Z]+\.com$',addr) r'([\w]+(\.[\w]+)*@[\w]+(\.[\w]+)+)' return True if m else False def is_valid_email2(addr): """匹配'<user@host.com>' 或 'user@host.com' """ m = re.match(r'(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$)',addr) return True if m else False # 测试: assert is_valid_email('someone@gmail.com') assert is_valid_email('bill.gates@microsoft.com') assert not is_valid_email('bob#example.com') assert not is_valid_email('mr-bob@example.com') assert is_valid_email2('<someone@gmail.com>') print('ok')

可以提取出带名字的Email地址:

  • <Tom Paris> tom@voyager.org => Tom Paris
  • bob@example.com => bob
代码参考
# coding:utf-8 # re 模块 import re def name_of_email(addr): return re.match(r'\<?([\w\s]+)\>?\s?(\w*)\@',addr).group(1) def name_of_email2(addr): return re.match(r'(<)?([\w\s]+)(?(1)(?:> \w+))@',addr).group(2) # 测试: assert name_of_email('<Tom Paris> tom@voyager.org') == 'Tom Paris' assert name_of_email('tom@voyager.org') == 'tom' print('ok')

其他

匹配网页 (http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*,]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)|([a-zA-Z]+.+.+[a-zA-Z0-9/_]+)