最近在研究如何录入一张doc试卷里面的选择题,开始使用python的doc库来匹配读取,但是由于doc的格式各不相同,很难适配各种类型,而且最好是可操作的那种。最后选用html + JavaScript来实现。不过遇到了各种坑,最后也只能说勉强处理了
第一个阶段
分别使用正则匹配题目和选项
const data =
"1.如果一个圆锥体的底面半径扩大2倍,高缩小为原来的一半,它的体积是原来体积的( )。 (本题分数:2分)\n A:2倍 B:一半 C:不变 D:无法确定\n2.有5张卡片,上面的数字分别是0、4、5、6、7,从中抽出3张所组成的三位数中能被4整除的有( )个。 (本题分数:2分)\n A、11\n B、12\n C、10\n D、15\n3.某村前年产苹果30万千克,去年增产20%,今年减产20%,今年产量为( )万千克。 (本题分数:2分)\n A)29\n B)31\n C)28.8\n D)29.2\n4.一个两位数除以5余3,除以7余5,这个两位数最大是( )。 (本题分数:2分)\n A.72\n B.37\n C.33\n D.68\n5.某班男生比女生多,男生相当于全班人数的( )。 (本题分数:2分)\n A:8/3\n B:8/19\n C:8/11\n D:11/19\n";
const parse = () => {
const titleRegex = /\d{1,2}(\.|、|.)\s*(.*[\u4e00-\u9fa5]{1,}.+)/g;
const optionsRegex = /([A-D])(:|:|)|\)|\.|、|.)\s*(\S+)(\s+|\t+|\n)/g;
const arr = [];
let titleIndex = 1;
let titleMatch = titleRegex.exec(data);
while (titleMatch) {
arr.push({
numberId: titleIndex,
question: {
title: titleMatch[2]
}
});
titleIndex = titleIndex + 1;
titleMatch = titleRegex.exec(data);
}
let optionsIndex = 1;
let optionMatch = optionsRegex.exec(data);
let optionItems = [];
let chooseIndex = 1;
while (optionMatch) {
optionItems.push({ key: optionMatch[1], content: optionMatch[3] });
if (optionsIndex % 4 === 0) {
let findItem = arr.find((item) => item.numberId === chooseIndex);
if (findItem) {
findItem.question.A =
optionItems[0].key === "A" ? optionItems[0].content : "";
findItem.question.B =
optionItems[1].key === "B" ? optionItems[1].content : "";
findItem.question.C =
optionItems[2].key === "C" ? optionItems[2].content : "";
findItem.question.D =
optionItems[3].key === "D" ? optionItems[3].content : "";
}
chooseIndex = chooseIndex + 1;
optionItems = [];
}
optionsIndex = optionsIndex + 1;
optionMatch = optionsRegex.exec(data);
}
console.log(JSON.stringify(arr, null, 2))
}
最后的结果如下,对于这种很简单的格式还是没问题的。
但是一旦遇到下面这种很复杂的,就熄火了.
1.( )是构成C语言程序的基本单位。
A、函数 B、过程 C、子程序 D、子例程
2.设有如下定义:
struck sk
{
int a;
float b;
} data;
int *p;
若要使P指向data中的a域,正确的赋值语句是
A) p=&a; B) p=data.a; C) p=&data.a; D)*p=data.a;
第二阶段改良
先匹配选项,然后给选项打标,用<<<[选项]>>>包裹起来,然后在匹配题目用{{{[标题]}}}包裹起来。最后分析出题目和每个选项
const optionsRegex = /(A(:|:|)|\)|\.|、|.)(.|\n)+?B(:|:|)|\)|\.|、|.)(.|\n)+?C(:|:|)|\)|\.|、|.)(.|\n)+?D(:|:|)|\)|\.|、|.)(.+))(\n|\s)+/g;
const titleRegex = />>>(\n)+\d{1,2}(\.|、|.)((.|\n)+?)<<</g;
const chooseRegex = /{{{((.|\n)+?)}}}<<<((.|\n)+?)>>>/g;
let copyData = data;
copyData = data.replace(optionsRegex, "<<<$1>>>\n");
copyData = ">>>\n" + copyData;
copyData = copyData.replace(titleRegex, ">>>{{{$3}}}<<<");
let index = 1;
let arr = [];
let chooseMatch = chooseRegex.exec(copyData);
while (chooseMatch) {
const title = chooseMatch[1].trim();
const chooseItem = chooseMatch[3];
const optionsRegexWithNoEnd = /A(:|:|)|\)|\.|、|.)((.|\n)+?)B(:|:|)|\)|\.|、|.)((.|\n)+?)C(:|:|)|\)|\.|、|.)((.|\n)+?)D(:|:|)|\)|\.|、|.)((.|\n)+)/g;
const findOptionMatch = optionsRegexWithNoEnd.exec(chooseItem);
if (findOptionMatch) {
arr.push({
numberId: index,
question: {
title: title,
A: findOptionMatch[2].trim(),
B: findOptionMatch[5].trim(),
C: findOptionMatch[8].trim(),
D: findOptionMatch[11].trim()
}
});
}
index = index + 1;
chooseMatch = chooseRegex.exec(copyData);
}
重要解决了
发表评论
所有评论(0)