201509-3-模版生成系统
问题
思路
- 用模版的没一行,去正则匹配
- 并得到匹配成功的子串,将
{{var}}按需替换
- var有,则用变量值替换
- 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)
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个字符 -
``'{{ .+? }}'` 100分 重点-非贪婪匹配
-
{{ [^}]+ }}100分 中间无 },来匹配关
还是抽象的,按题意居然只能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']