今天看到以下这段代码:
import re
_USER_RE = r'''(?P<user>[^:@]+|'[^']+'|"[^"]+")'''
_PASSWORD_RE = r'''(?P<password>[^@]+|'[^']+'|"[^"]+")'''
_CREDS_RE = r'{}(?::{})?'.format(_USER_RE, _PASSWORD_RE)
FTP_RE = re.compile(r'^ftp://(?:{}@)?(?P<abs_path>.*)$'.format(_CREDS_RE))
source = 'ftp://anonymous:guest@ftp.ncbi.nlm.nih.gov/codepackage'
m = FTP_RE.search(source)
user = m.group('user') or 'anonymous'
password = m.group('password') or 'guest'
server, path_dir = m.group('abs_path').split('/', 1)
觉得有几点很不错:
1、把每个关键信息的提取分开写,提高代码的可读性
2、过程中用到的一些表达式我还不清楚,需要深入了解,比如 ?:: 什么意思?
3、遵守很好的代码规范
接下来我尝试解释一下匹配过程:
1、FTP_RE整体分为2部分, 第一部分用CREDS_RE匹配 anonymous:guest, 用后面.*匹配ftp.ncbi.nlm.nih.gov/codepackage
2、CREDS_RE, 用USER_RE匹配了nonymous,用PASWWORD_RE匹配了guest。?::{} 其中第二个:匹配了anonymous:guest中间的:. ?P<user>[^:@]+|'[^’]+’|”[^”]+”) 表示用户名可以包含单双引号
3、说明 (?::{})? 这个正则表达式中,两个?含义不同,第一个和?:结合在一起,表示非捕获匹配, 第二个?表示括号内容的0次或一次
一些知识点:
1、 什么是非捕获匹配可以看
这篇博客
2、 (?P<user>xxxx), 这个叫组匹配,user表示组名,xxxx表示这个组的匹配格式,组匹配可以看看
这篇文章
https://blog.csdn.net/whaoXYSH/article/details/22295317
3、如何看匹配组的内容?
print(m.groups())
print(m.groupdict())
结果:
(‘anon[ymous’, ‘234[faa’, ‘ftp.ncbi.nlm.nih.gov/codepackage’)
{‘user’: ‘anon[ymous’, ‘password’: ‘234[faa’, ‘abs_path’: ‘ftp.ncbi.nlm.nih.gov/codepackage’}
可以看到,只要?:表示非捕获组没有显示在这里。
4、|在正则表表示或的意思