简单的正则匹配,看文档就可以看懂,涉及到一些位置限定的,算是一些进阶内容,记录下学习成果。
- 非捕获匹配:
(?:...)
非捕获匹配后的结果是不能引用的。
-
顺序肯定环视匹配:
(?=...)
顺序肯定环视匹配,匹配=后面的内容,例如 r'(?=a+)\w+',
匹配时若匹配到\w+数字字母下划线时,例如字符串@abcef,将会匹配到abcef,
从第一个字符a开始向右顺序匹配?=后的表达式,如果匹配到a+,则成功,依次查找。
用来限定匹配的开头字符肯定范围。pattern = r'(?=a+)\w+' str_ = '@abcef' print(re.search(pattern, str_))
-
顺序否定环视匹配:
(?!...)
顺序否定环视匹配,匹配不符合!后面的内容,例如 r'(?!a+)\w+',
匹配时若匹配到\w+,字符串@abcef 将匹配到abcef,
从第一个字符a开始向右顺序匹配?!后的表达式,匹配不是a+,则成功,依次查找。
用来限定匹配的开头字符否定范围。pattern = r'(?!a+)\w+' str_ = '@abcef' print(re.search(pattern, str_))
-
逆序肯定环视匹配:
(?<=...)
逆序肯定环视匹配,匹配=后面内容到当前位置,例如 r'(?<=abc)\w+',
逆序与顺序不同的是,=后面的表达式数量一定是确定的,
因为是反向查找,不确定数量无法匹配。例如字符串@abcef,将会匹配到abcef,
从第一个字符逆序向左匹配,若字符符合<=后的匹配规则,则成功,依次查找。
用来限定匹配的字符串跟随字符的肯定范围。pattern = r'(?<=abc)\w+' str_ = '@abcef' print(re.search(pattern, str_))
-
逆序否定环视匹配:
(?<!...)
逆序否定环视匹配,匹配当前位置之前不符合!后的内容,例如 r'(?<!@)\w+',
匹配时若匹配到 \w+,字符串@abcef将匹配到abcef,
从第一个字符a开始逆序向左匹配,若字符不符合 <! 后的匹配规则,则成功,依次查找。
用来限定匹配的字符串跟随字符的否定范围。pattern = r'(?<!@)\w+' str_ = '@abcef' print(re.search(pattern, str_))
-
三元表达式形式匹配(可能名字取的不准确):
(?(id/name)yes-pattern|no-pattern)
表达式形式宛如三元表达式,我自己称呼它为三元表达式匹配。
如果给定的id或name(id表示分组的id,从0开始)存在,
将会尝试yes-pattern,否则尝试no-pattern。
比如下面的邮箱模式匹配,整体模式分为三组,r'(<)?(\w+@\w+(?:\.\w+))(?(1)>|$)'
第一组为整个模式字符串,id为0,
第二组为开头的 < ,id为1,
第三组为\w+@\w+(?:\.\w+),(?:...)为非捕获匹配,
(?(1)>|$)表示如果匹配到了id为1的组,就去匹配 > ,
否则匹配空结尾。
这里的目的是为了匹配到 <test123@qq.com>或test123@qq.com的内容,而非 <test123@qq.com 或 test123@qq.com>,即保证了前后 <>完整性,可以同时存在,可以同时不存在。email_pattern = r'(<)?(\w+@\w+(?:\.\w+))(?(1)>|$)' re_compile = re.compile(email_pattern) email_str = 'sdfsdjf@dsjkf.com' print(re.fullmatch(email_pattern, email_str))
其他的 ?# 注释等内容,暂未明白表达意思。
后记:
位置限定其实限定的是位置信息,而不记录位置上的字符信息,这一点还是区别于普通模式的匹配的。
举个例子:
金钱的显示格式一般是三位数一个逗号,形如 ¥486,562,123
这时候如果得到的是个原始字符串:
num_str = '¥486562123'
可以根据位置限定的正则来完成这样的需求。
首先规则为,从右向左,每三位前面加一个逗号,但是逗号前必须至少有一位数字,表现为正则:
p_num = r'(?<=\d)(?=(\d{3})+$)'
上面正则逆序肯定环视确定了该位置左侧一定存在一位数字,顺序肯定环视确定了该位置右侧一定存在多组以三个数字为一组的字符串,直至字符串尾部。
按规则替换:
new_num = re.sub(p_num, ',', num_str)