#!/usr/bin/env/python # -*- coding:utf-8 -*- import re, os import configs from utils.washutil import table_label_cleal import numpy as np from PIL import Image def option2block(option_con, item_no_type): """ 选择题选项切分 对于选项切分部分,最好也像题号一样先自我切分纠错,但这样老师如果手误打错了字母,可能就解析出错!!!!! :return: """ def del_table(ss): ss = re.sub(r"?t[dr]>|?tbody>|?table>|?div>|?p>", "", ss.replace("
", " ")) return ss # print('***********',option_con) if '
(A\s*[..、、::].+?|\(A\)\s*[..、、]?.+?) |
(A\s*[..、、::].+?|\(A\)\s*[..、、]?.+?) |
\s*(A\s*[、、..::]|\(A\)\s*[、、..]?)(.+?)", r"\n【【\1】】\2", option_con, re.S)
if re.search("\n\s*C", option_con) is None and re.search("\n\s*c", option_con):
option_con = re.sub("\n\s*c", "\nC", option_con)
option_con = re.sub(r"(\n\s*(]).)*?/>\s*)+?\s*)(A[、、..::].+?)", r"\1\n\4", option_con.strip())
con = re.sub(r"\n\s*([A-H])\s*[、、..::](.+?)", r"\n【【\1、】】\2", option_con.strip()) # 行首的A、不能考虑,故得用strip
if item_no_type == 1 and len(re.findall(r'【【[A-H]\s*[..、、]】】', con)) <= 2 and \
len(re.findall(r'\([A-H]\)', con)) > 2: # 针对题干是第一种类型,选项是第二种类型的情况
item_no_type = 2
if item_no_type == 2:
con = re.sub(r"\n\s*\(([A-Hc])\)\s*[、、..]?(.+?)", r"\n【【\1、】】\2", option_con)
if item_no_type == 1:
if len(re.findall(r'【【[A-H]\s*[..、、]】】', con)) <= 3:
while re.search(r"\n\s*[A-H]\s*\s+)(?\s+)(? 1:
stem_opt = table_label_cleal(con_list[0])
con_list = list(map(del_table, con_list[1:]))
con_list.insert(0, stem_opt) # 题干中的表格不需要清洗
return con_list, con
recur_n = 1 # 递归次数
def option_structure(one_item, con, ans, item_no_type, is_danti=0):
"""
选择题选项拆分结构化
还需要判断一下 选项个数与题型的对应!!!!
:return:
"""
global recur_n
# print(con)
# print('----------------------')
if recur_n > 2:
if 'options' not in one_item:
one_item["errmsgs"].append("选项格式不正确")
recur_n = 1
return one_item
ans = re.sub("[;;.]+", "", ans)
ans2 = []
for a in ans.split("#"):
if 0 < len(a.replace(" ", "")) < 8:
ans2.append("、".join(re.findall(r"[A-G]", a.replace("c", "C"))))
one_item["key"] = "; ".join(ans2)
options_rank = get_options_arrange(one_item["stem"])
# print("id:", one_item['item_id'])
# print("options_rank:",options_rank)
con_list, repl_con = option2block(con, item_no_type)
# print(len(con_list), con_list)
# print('----------------------------')
# 初筛
if len(con_list) < 5:
opt_letter = re.findall(r"【【([A-H])\s*[..、、]】】", repl_con)
if opt_letter and opt_letter[0] == 'B' and re.search("\s*A\s*[..、、].+?$", con_list[0]):
re_split = re.sub("()\s*A\s*[..、、](.+?)$", r"\1【【A、】】\2", con_list[0])
con_list[0] = re_split.split("【【A、】】")[0]
con_list.insert(1, re_split.split("【【A、】】")[1])
if len(con_list) >= 5:
pattern_1 = re.compile(r"\s([1-9]|1[0-9])[..、、].+?([是为有]|等于)[((]\s*[))]\n", re.S)
pattern_2 = re.compile(r"\s\(([1-9]|1[0-9])\).+?([是为有]|等于)[((]\s*[))]\n", re.S)
pattern_3 = re.compile(r"([是为有]|等于)[((]\s*[))]\n", re.S)
# 第一个错误针对题目中没有答案解析的情况,不然就是选项切分错误
if not is_danti:
if (item_no_type == 1 and any([True for op in con_list[1:] if re.search(pattern_1, op)])) or \
(item_no_type == 2 and any([True for op in con_list[1:] if re.search(pattern_2, op)])):
one_item["errmsgs"].append("本题选项与下一题题干间没有换行符,请注意重新换行!!!") # 一般只有一题和上一题连在一起
one_item['spliterr_point'] = one_item['item_id']
return one_item
elif any([True for op in con_list[1:] if re.search(pattern_3, op)]):
one_item["errmsgs"].append("本题的下一题的题号有问题,请注意重新输入!!!")
one_item['spliterr_point'] = one_item['item_id']
# ------------------------------------------------------------------------
aft_opt = [] # 针对选项后是题目图片的情况
if "\n" in con_list[-1]:
ccon = re.split("\n+", con_list[-1])
while re.match("|\n)\s*$|\s+$", "", i) for i in con_list[1:]],
"options_rank": options_rank,
}) # , "options_num": len(con_list[1:])
else:
# 初次选项拆分的错误判断
con_list = option_label_correct(opt_letter, con_list, repl_con)
# double_l = [key for key, value in dict(Counter(opt_letter)).items() if value > 1]
if type(con_list) == str:
one_item["errmsgs"].append(con_list)
return one_item
else:
# con_list = pic_transfer(con_list)
if con_list:
return dict(one_item,
**{"stem": con_list[0],
"options": [re.sub("(
|\n)\s*$|\s+$", "", i) for i in con_list[1:]],
"options_rank": options_rank,
})
# return dict(one_item, **dict(zip(["stem","A","B","C","D"], con_list)))
else:
# 选项可能放在表格中
is_fail = 0
con_list2 = re.split(r"\n+", con)
errmsgs = ""
if len(con_list2) == 2: # 选项是4个图片组成的情况
option_array = len(re.findall("(^|\n) 2: # 排列情况
options_rank = 1
elif option_array > 1:
options_rank = 3
else:
options_rank = 2
ims = con_list2[1].split("|\n)\s*$|\s+$", "", i) for i in con_list2[1:]],
"options_rank": options_rank,
})
else:
errmsgs = """选项格式不正确,请改为: A.xxxx (换行或多空几格) B.xxx。
【注意】1>>选项和题干间要换行,选项不要放在表格中;2>>选项【如A.】重新手输;
3>>选项太长时,每项之间要换行,上一项的内容不要与下一项在同一行!!"""
is_fail = 1
else:
con_list3 = re.split(r"\n(?=|\n)\s*$|\s+$", "", i) for i in con_list3[1:]],
"options_rank": options_rank,
})
else:
errmsgs = """选项格式不正确,请改为: A.xxxx (换行或多空几格) B.xxx。
【注意】1>>选项和题干间要换行,选项不要放在表格中;2>>选项【如A.】重新手输
3>>选项太长时,每项之间要换行,上一项的内容不要与下一项在同一行!!"""
is_fail = 1
op_con = re.split("[((]\s*[))]", con)[-1]
stem_con = "".join(re.split("[((]\s*[))]", con)[:-1])+"( )\n"
if is_fail:
if "table" in op_con:
to_clean_con = re.findall('
A | B | C | D |
汽油 | 天然气 | 浓硫酸 | 氢氧化钠 |