CCF-CSP 201509-3-模版生成系统 (Python) 正则 defaultdict 满分实现

博客主要介绍了如何使用Python的defaultdict和正则表达式解决CCF CSP 201509-3-模版生成系统的问题。通过读题、分析思路,利用正则匹配和defaultdict简化处理,实现了模板的变量替换功能,以达到满分解决方案。
摘要由CSDN通过智能技术生成

201509-3-模版生成系统

问题

image-20230309165248797

image-20230309184412101

image-20230309165003921

思路

  1. 用模版的没一行,去正则匹配
  2. 并得到匹配成功的子串,将{{var}}按需替换
    1. var有,则用变量值替换
    2. var无,则用空串替换

实现

读题就写
import re

m, n = map(int, input().strip().split()) # m:模板的行数,n:变量个数

template_list = [input().strip() for _ in range(m)] # 模版列表,下标[0,m-1]
var_dict = dict() # 变量字典,例如{'name': 'David Beckham', 'email': 'david@beckham.com'}
key_set = set() # 变量集合,例如{'name': 'David Beckham', 'email': 'david@beckham.com'}
for i in range(n): # {'name', 'email'}
  key, val =  input().strip().split(' ', maxsplit=1) # key:变量名,var:变量值
  key_set.add(key)
  var_dict.setdefault(key, val.split('"')[1]) # val.split('"')[1]去除变量值的双引号

for i, line in enumerate(template_list): # i:模版列表下标,line:template_list[i]的值
  pat = re.compile('{{ [a-zA-Z_][\w_]{0,15} }}') # pat正则匹配模式,匹配{{ var }}
  res = pat.findall(line) # 匹配到的[{{ var }},]列表
  if len(res) > 0:
    for j in res:
      k = j.split()[1] # k:var
      if k in key_set:
        template_list[i] = template_list[i].replace(j, var_dict[k])
      else:
        template_list[i] = template_list[i].replace(j, '')
for i in template_list:
  print(i)

image-20230309184938912

1、.split(sep=None, maxsplit=-1)

maxsplit参数是可选的,用于指定要分割的最大次数。如果未提供maxsplit参数,则默认将所有匹配的分隔符都视为分割点。

⚠️:只能匹配60分,最后发现了问题所在是

template_list = [input().strip() for _ in range(m)]

strip()删除字符串开头和结尾的所有空白字符,包括空格、制表符和换行符,他把模版文本给伤了,去除后

用以下三种正则匹配方式

  • '{{ [a-zA-Z_][\w]{0,15} }}' 90分 按题意,变量名由大小写字母、数字和下划线
    构成,且第一个字符不是数字长度不超过16个字符image-20230309205021922

  • ``‘{{ .+? }}’` 100分 重点-非贪婪匹配

  • {{ [^}]+ }} 100分 中间无 },来匹配关image-20230309205032092

还是抽象的,按题意居然只能90分。

用collections.defaultdict来简化

访问defaultdict无key的情况,不会报错,返回None正好做空串改值

import re
from collections import defaultdict

m, n = [int(it) for it in input().rstrip().split(' ')] # m:模板的行数,n:变量个数
lines = [] # 模版列表,下标[0,m-1]
mode = defaultdict(str) # 变量的defaultdict字典
for i in range(m):
    lines.append(input())
for i in range(n):
    name, value = input()[:-1].split(' "') 
    mode[name] = value
for i in range(m): # i模版列表的下标
    for it in re.findall('{{ .+? }}', lines[i]): # 找到模版中所有 {{ var }}
        lines[i] = lines[i].replace(it, mode[it[3:-3]]) # 巧妙结合defaultdict来替换
    print(lines[i])

1、name, value = input()[:-1].split(' "')

exp-input():name “David Beckham”
[:-1]:name "David Beckham
.split(’ "') :[‘name’, ‘David Beckham’]

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RessMatthew

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值