如何使用JavaScript来批量录入试卷中的选择题(正则学习)

最近在研究如何录入一张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);
    }

重要解决了


相关标签:
  • 批量录入试卷
  • 正则表达式
2人点赞

发表评论

当前游客模式,请登陆发言

所有评论(0)