涉及嵌套分组与命名分组的正则练习一则

涉及嵌套分组与命名分组的正则练习一则

转载请注明出处:https://blog.csdn.net/jpch89/article/details/88022328



1. 题目

有文本若干行如下,请写出正则匹配出以 param 开头的参数信息,输出格式为:字段名称、字段类型(不带尖括号)、是否可选(不带尖括号)和字段含义四部分内容。

"""
#param  nickname    <str>    昵称
#param  sex    <int>    <可选>    学员性别,1 男,2 女
"""

2. 使用嵌套分组

分析

  • 第一条记录没有 <可选>,而第二条记录有 <可选>,所以要把 <可选> 整体作为一个分组进行匹配,然后在里面嵌套一个分组,匹配去掉尖括号的内容。
  • 假如作为整体的那个分组的编号为 n,里面嵌套的分组的编号分别为 n + 1n + 2n + 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

猜你喜欢

转载自blog.csdn.net/jpch89/article/details/88022328
今日推荐