涉及嵌套分组与命名分组的正则练习一则
转载请注明出处:https://blog.csdn.net/jpch89/article/details/88022328
1. 题目
有文本若干行如下,请写出正则匹配出以 param
开头的参数信息,输出格式为:字段名称、字段类型(不带尖括号)、是否可选(不带尖括号)和字段含义四部分内容。
"""
#param nickname <str> 昵称
#param sex <int> <可选> 学员性别,1 男,2 女
"""
2. 使用嵌套分组
分析
- 第一条记录没有
<可选>
,而第二条记录有<可选>
,所以要把<可选>
整体作为一个分组进行匹配,然后在里面嵌套一个分组,匹配去掉尖括号的内容。 - 假如作为整体的那个分组的编号为
n
,里面嵌套的分组的编号分别为n + 1
、n + 2
、n + 3
等等。
代码
import re
text = """
#param nickname <str> 昵称
#param sex <int> <可选> 学员性别,1 男,2 女
"""
# 使用嵌套分组
p = re.compile(r'#param\s+([a-zA-Z]+)\s+<([a-zA-Z]+)>(\s+<(.+)>)?\s+(.+)')
result = p.finditer(text)
for i in result:
print(i.group(1, 2, 4, 5))
"""
('nickname', 'str', None, '昵称')
('sex', 'int', '可选', '学员性别,1 男,2 女')
"""
补充
-
经验:正则匹配写的越严格越好,比如
str
的匹配尽量写成'[a-zA-Z]+'
,而不要写成'.+'
,不然容易多匹配到其它的东西。 -
group
函数的帮助文档
Help on built-in function group:
group(...) method of re.Match instance
group([group1, ...]) -> str or tuple.
Return subgroup(s) of the match by indices or names.
For 0 returns the entire match.
group
函数说明- 只传递一个参数时,返回相应分组的匹配结果
- 传递多于一个参数时,返回由匹配结果组成的元组
- 接收的参数可以是数字或者字符串名称
3. 使用命名分组
分析
- 上面使用嵌套分组的方法,虽然成功匹配到了所有信息,但是调用
group
函数时传入的分组编号容易出错,尤其是在有嵌套分组存在的情况下。
为了改善这一弊端,可以使用命名分组。 - 命名分组的写法是
(?P<分组名>要匹配的内容)
。 - 在正则表达式中可以通过
(\数字)
来引用之前匹配到的分组。 - 有了命名分组之后,可以在正则表达式中使用
(?P=name)
来匹配之前匹配到的命名分组。
代码
import re
text = """
#param nickname <str> 昵称
#param sex <int> <可选> 学员性别,1 男,2 女
"""
# 使用命名分组
p = re.compile(r'#param\s+(?P<name>[a-zA-Z]+)\s+<(?P<type>[a-zA-Z]+)>(\s+<(?P<opt>.+)>)?\s+(?P<desc>.+)')
result = p.finditer(text)
for i in result:
print(i.group('name', 'type', 'opt', 'desc'))
"""
('nickname', 'str', None, '昵称')
('sex', 'int', '可选', '学员性别,1 男,2 女')
"""
完成于 2019.02.28