鱼C论坛

 找回密码
 立即注册
查看: 6264|回复: 14

[已解决]如何将字符串按特定规律转换成json

[复制链接]
发表于 2021-2-23 01:09:58 | 显示全部楼层 |阅读模式
60鱼币
本帖最后由 genius_7321 于 2021-2-23 01:12 编辑

希望能够用vue.js实现如下效果:
给定字符串:
  1. <p>1.题目,(),题目部份。 </p>
  2. <p>A:答案A</p>
  3. <p>B:答案B</p>
  4. <p>C:答案C</p>
  5. <p>D:答案D</p>
  6. <p>正确答案为:B</p>
  7. <p>解析:有的题目可能会有解析 </p>

  8. <p>2. 题目,(),题目部份。是(B) </p>
  9. <p>A:答案A</p>
  10. <p>B:答案B</p>
  11. <p>C:答案C</p>


  12. <p>3.题目,(),题目部份。 </p>
  13. <p>A:答案A</p>
  14. <p>B:答案B</p>
  15. <p>C:答案C</p>
  16. <p>D:答案D</p>
  17. <p>C:答案E</p>
  18. <p>D:答案F</p>
  19. <p>正确答案为:ABC</p>

  20. <p>4. 题目,(),题目部份。(B) </p>
  21. <p>A:答案A</p>
  22. <p>B:答案B</p>
  23. <p>C:答案C</p>
  24. <p>D:答案D</p>

  25. <p>5题目部份。  </p>
  26. <p>正确  错误  </p>
  27. <p>正确答案为:正确 </p>
  28. <p>解析:有的题目可能会有解析 </p>

  29. <p>6.题目部份。(正确)  </p>
  30. <p>A:正确</p>
  31. <p>B:错误</p>
复制代码


原始字符串是这样的:
111.png

1、每组p标签包裹一个value,如"<p>数字."开头,到下一个“</p>”为title,然后是optionA,等等以此类推。
2、每组p标签之间没有换行,没有空格,这里为了方便阅读人工编辑了格式。
3、正确答案有可能是在选项最后,以"<p>正确答案"开头出现,也有可能出现在title的(B)中,如果可能的话,希望能自动判断。
4、题型分为单选、多选、判断,希望能自动判断,在json中增加type字段。
5、选项不固定为ABCD(判断题固定只有AB或者对错或者√×),单选多选有可能只有ABC,或者ABCDEF选项。


期待输出如下对象数组:
微信截图_20210223010640.png
最佳答案
2021-2-23 01:09:59
本帖最后由 Darth_EF 于 2021-2-25 16:52 编辑

  1.             // 把字符串转换成 node 数组
  2.             var str="<p>1.题目,(),题目部份。 </p><p>A:答案A</p><p>B:答案B</p><p>C:答案C</p><p>D:答案D</p><p>正确答案为:B</p><p>解析:有的题目可能会有解析 </p><p>2. 题目,(),题目部份。是(B) </p><p>A:答案A</p><p>B:答案B</p><p>C:答案C</p><p>3.题目,(),题目部份。 </p><p>A:答案A</p><p>B:答案B</p><p>C:答案C</p><p>D:答案D</p><p>C:答案E</p><p>D:答案F</p><p>正确答案为:ABC</p><p>4. 题目,(),题目部份。(B) </p><p>A:答案A</p><p>B:答案B</p><p>C:答案C</p><p>D:答案D</p><p>5.题目部份。  </p><p>正确  错误  </p><p>正确答案为:正确 </p><p>解析:有的题目可能会有解析 </p><p>6.题目部份。(正确)  </p><p>A:正确</p><p>B:错误</p>"
  3.             var temp=document.createElement("div");
  4.             temp.innerHTML=str;
  5.             var nodeList=temp.children;

  6.             class Cr{
  7.                 /**
  8.                  * @param {Array<CrNode>} CrNodes
  9.                  */
  10.                 constructor(CrNodes){
  11.                     this.crs=CrNodes;
  12.                     this.qObjs=[];
  13.                 }
  14.                 /**
  15.                  * @param {Array<Element>} elements
  16.                  * @returns {Array<QOBJ>} 返回 QOBJ 数组
  17.                  */
  18.                 loadElement(elements){
  19.                     this.qObjs=[];
  20.                     for(var i=0;i<elements.length;++i){
  21.                         for(var j=this.crs.length-1;j>=0;--j){
  22.                             if(this.crs[j].regexp.test(elements[i].innerHTML)){
  23.                                 this.crs[j].callback.call(this,elements[i].innerHTML);
  24.                                 this.crs=this.crs[j].next;
  25.                                 j=this.crs.length-1;
  26.                                 break;
  27.                             }
  28.                         }
  29.                     }
  30.                     for(var i=this.qObjs.length-1;i>=0;--i){
  31.                         if(!this.qObjs[i].QBType){
  32.                             var tempStr=this.qObjs[i].answer,typeStr;
  33.                             if(tempStr.length>1){
  34.                                 if((/^\w+/).test(tempStr)){
  35.                                     typeStr="MC";
  36.                                 }else{
  37.                                     typeStr="JD";
  38.                                     if(this.qObjs[i].answer.indexOf("正确")!=-1){
  39.                                         this.qObjs[i].answer="A";
  40.                                     }else{
  41.                                         this.qObjs[i].answer="B";
  42.                                     }
  43.                                 }
  44.                             }else{
  45.                                 typeStr="SC";
  46.                             }
  47.                             this.qObjs[i].QBType=typeStr;
  48.                         }
  49.                     }
  50.                     return this.qObjs;
  51.                 }
  52.             }
  53.             class CrNode{
  54.                 /**
  55.                  * @param {RegExp} regexp       匹配字符串的正则表达式
  56.                  * @param {Function} callback   callback.call(Cr,elements.innerHTML);
  57.                  * @param {Array<RegExp>} next  匹配到之后修改当前的匹配
  58.                  */
  59.                 constructor(regexp,callback,next){
  60.                     this.regexp=regexp;
  61.                     this.next=next;
  62.                     this.callback=callback;
  63.                 }
  64.             }
  65.             class QOBJ{
  66.                 constructor(){
  67.                     this.id=0;
  68.                     this.title="";
  69.                     this.answer="";
  70.                     this.analysis="";
  71.                     this.QBType="";
  72.                 }
  73.                 /**
  74.                  * @param {String} str
  75.                  */
  76.                 addOption(str){
  77.                     var i=0,tempString="option"+String.fromCharCode(i+65);
  78.                     while(this[tempString]){
  79.                         ++i;
  80.                         tempString="option"+String.fromCharCode(i+65);
  81.                     }
  82.                     this[tempString]=str;
  83.                 }
  84.                 getOptionLength(){
  85.                     var i=0,tempString="option"+String.fromCharCode(i+65);
  86.                     while(this[tempString]){
  87.                         ++i;
  88.                         tempString="option"+String.fromCharCode(i+65);
  89.                     }
  90.                     return i;
  91.                 }
  92.             }

  93.             var titleCr=new CrNode(/^[0-9]+\.[.\n\r]*/,function(str){
  94.                 var i=this.qObjs.length-1;
  95.                 i=this.qObjs.push(new QOBJ());
  96.                 var temp=str.match((/[\((]+([\w正确错误]+)[\))]+/));
  97.                 if(temp){
  98.                     this.qObjs[i-1].answer=temp[1];
  99.                 }
  100.                 this.qObjs[i-1].title=str.slice(str.indexOf('.')+1);
  101.                 this.qObjs[i-1].id=parseInt(str.slice(0,str.indexOf('.')));
  102.             });
  103.             var optionCr=new CrNode(/^[a-z]|[A-Z]+[::][.\n\r]*/,function(str){
  104.                 var i=this.qObjs.length-1;
  105.                 this.qObjs[i].addOption(str.slice(str.indexOf(/[::]/)+1));
  106.             });
  107.             var optionBoolCr=new CrNode(/^[正确 错误]+/,function(str){
  108.                 var i=this.qObjs.length-1;
  109.                 this.qObjs[i].addOption("正确");
  110.                 this.qObjs[i].addOption("错误");
  111.                 this.qObjs[i].QBType="JD"
  112.             });
  113.             var answerCr=new CrNode(/^正确答案为[::][.\n\r]*/,function(str){
  114.                 var i=this.qObjs.length-1;
  115.                 var tempStr=str.slice("正确答案为:".length),typeStr="";

  116.             });
  117.             var analysisCR=new CrNode(/^解析[::][.\n\r]*/,function(str){
  118.                 var i=this.qObjs.length-1;
  119.                 this.qObjs[i].analysis=str.slice("解析:".length);
  120.             });
  121.             titleCr.next=[optionCr,optionBoolCr];
  122.             optionCr.next=[titleCr,optionBoolCr,optionCr,answerCr];
  123.             optionBoolCr.next=[titleCr,optionBoolCr,optionCr,answerCr];
  124.             answerCr.next=[titleCr,analysisCR];
  125.             analysisCR.next=[titleCr];
  126.             
  127.             var d=new Cr([titleCr]);
  128.             var c=d.loadElement(nodeList);

  129.             console.log(JSON.stringify(c));
复制代码


QQ截图20210225163410.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-2-23 01:09:59 | 显示全部楼层    本楼为最佳答案   
本帖最后由 Darth_EF 于 2021-2-25 16:52 编辑

  1.             // 把字符串转换成 node 数组
  2.             var str="<p>1.题目,(),题目部份。 </p><p>A:答案A</p><p>B:答案B</p><p>C:答案C</p><p>D:答案D</p><p>正确答案为:B</p><p>解析:有的题目可能会有解析 </p><p>2. 题目,(),题目部份。是(B) </p><p>A:答案A</p><p>B:答案B</p><p>C:答案C</p><p>3.题目,(),题目部份。 </p><p>A:答案A</p><p>B:答案B</p><p>C:答案C</p><p>D:答案D</p><p>C:答案E</p><p>D:答案F</p><p>正确答案为:ABC</p><p>4. 题目,(),题目部份。(B) </p><p>A:答案A</p><p>B:答案B</p><p>C:答案C</p><p>D:答案D</p><p>5.题目部份。  </p><p>正确  错误  </p><p>正确答案为:正确 </p><p>解析:有的题目可能会有解析 </p><p>6.题目部份。(正确)  </p><p>A:正确</p><p>B:错误</p>"
  3.             var temp=document.createElement("div");
  4.             temp.innerHTML=str;
  5.             var nodeList=temp.children;

  6.             class Cr{
  7.                 /**
  8.                  * @param {Array<CrNode>} CrNodes
  9.                  */
  10.                 constructor(CrNodes){
  11.                     this.crs=CrNodes;
  12.                     this.qObjs=[];
  13.                 }
  14.                 /**
  15.                  * @param {Array<Element>} elements
  16.                  * @returns {Array<QOBJ>} 返回 QOBJ 数组
  17.                  */
  18.                 loadElement(elements){
  19.                     this.qObjs=[];
  20.                     for(var i=0;i<elements.length;++i){
  21.                         for(var j=this.crs.length-1;j>=0;--j){
  22.                             if(this.crs[j].regexp.test(elements[i].innerHTML)){
  23.                                 this.crs[j].callback.call(this,elements[i].innerHTML);
  24.                                 this.crs=this.crs[j].next;
  25.                                 j=this.crs.length-1;
  26.                                 break;
  27.                             }
  28.                         }
  29.                     }
  30.                     for(var i=this.qObjs.length-1;i>=0;--i){
  31.                         if(!this.qObjs[i].QBType){
  32.                             var tempStr=this.qObjs[i].answer,typeStr;
  33.                             if(tempStr.length>1){
  34.                                 if((/^\w+/).test(tempStr)){
  35.                                     typeStr="MC";
  36.                                 }else{
  37.                                     typeStr="JD";
  38.                                     if(this.qObjs[i].answer.indexOf("正确")!=-1){
  39.                                         this.qObjs[i].answer="A";
  40.                                     }else{
  41.                                         this.qObjs[i].answer="B";
  42.                                     }
  43.                                 }
  44.                             }else{
  45.                                 typeStr="SC";
  46.                             }
  47.                             this.qObjs[i].QBType=typeStr;
  48.                         }
  49.                     }
  50.                     return this.qObjs;
  51.                 }
  52.             }
  53.             class CrNode{
  54.                 /**
  55.                  * @param {RegExp} regexp       匹配字符串的正则表达式
  56.                  * @param {Function} callback   callback.call(Cr,elements.innerHTML);
  57.                  * @param {Array<RegExp>} next  匹配到之后修改当前的匹配
  58.                  */
  59.                 constructor(regexp,callback,next){
  60.                     this.regexp=regexp;
  61.                     this.next=next;
  62.                     this.callback=callback;
  63.                 }
  64.             }
  65.             class QOBJ{
  66.                 constructor(){
  67.                     this.id=0;
  68.                     this.title="";
  69.                     this.answer="";
  70.                     this.analysis="";
  71.                     this.QBType="";
  72.                 }
  73.                 /**
  74.                  * @param {String} str
  75.                  */
  76.                 addOption(str){
  77.                     var i=0,tempString="option"+String.fromCharCode(i+65);
  78.                     while(this[tempString]){
  79.                         ++i;
  80.                         tempString="option"+String.fromCharCode(i+65);
  81.                     }
  82.                     this[tempString]=str;
  83.                 }
  84.                 getOptionLength(){
  85.                     var i=0,tempString="option"+String.fromCharCode(i+65);
  86.                     while(this[tempString]){
  87.                         ++i;
  88.                         tempString="option"+String.fromCharCode(i+65);
  89.                     }
  90.                     return i;
  91.                 }
  92.             }

  93.             var titleCr=new CrNode(/^[0-9]+\.[.\n\r]*/,function(str){
  94.                 var i=this.qObjs.length-1;
  95.                 i=this.qObjs.push(new QOBJ());
  96.                 var temp=str.match((/[\((]+([\w正确错误]+)[\))]+/));
  97.                 if(temp){
  98.                     this.qObjs[i-1].answer=temp[1];
  99.                 }
  100.                 this.qObjs[i-1].title=str.slice(str.indexOf('.')+1);
  101.                 this.qObjs[i-1].id=parseInt(str.slice(0,str.indexOf('.')));
  102.             });
  103.             var optionCr=new CrNode(/^[a-z]|[A-Z]+[::][.\n\r]*/,function(str){
  104.                 var i=this.qObjs.length-1;
  105.                 this.qObjs[i].addOption(str.slice(str.indexOf(/[::]/)+1));
  106.             });
  107.             var optionBoolCr=new CrNode(/^[正确 错误]+/,function(str){
  108.                 var i=this.qObjs.length-1;
  109.                 this.qObjs[i].addOption("正确");
  110.                 this.qObjs[i].addOption("错误");
  111.                 this.qObjs[i].QBType="JD"
  112.             });
  113.             var answerCr=new CrNode(/^正确答案为[::][.\n\r]*/,function(str){
  114.                 var i=this.qObjs.length-1;
  115.                 var tempStr=str.slice("正确答案为:".length),typeStr="";

  116.             });
  117.             var analysisCR=new CrNode(/^解析[::][.\n\r]*/,function(str){
  118.                 var i=this.qObjs.length-1;
  119.                 this.qObjs[i].analysis=str.slice("解析:".length);
  120.             });
  121.             titleCr.next=[optionCr,optionBoolCr];
  122.             optionCr.next=[titleCr,optionBoolCr,optionCr,answerCr];
  123.             optionBoolCr.next=[titleCr,optionBoolCr,optionCr,answerCr];
  124.             answerCr.next=[titleCr,analysisCR];
  125.             analysisCR.next=[titleCr];
  126.             
  127.             var d=new Cr([titleCr]);
  128.             var c=d.loadElement(nodeList);

  129.             console.log(JSON.stringify(c));
复制代码


QQ截图20210225163410.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-2-24 23:01:22 | 显示全部楼层
本帖最后由 Darth_EF 于 2021-2-25 16:47 编辑

我虽然会写,但是不会用vue。
其实挺简单的,但是我不会写vue。
如果能保证运行环境是浏览器的window线程的话就更简单了(可以直接用document接口的方法); 虽然不保证环境也能写,但是要多写段代码去分析xml

如果要的话,我可以用js给你写; 而且请告诉我你的运行环境是什么。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-2-25 01:10:07 | 显示全部楼层
Darth_EF 发表于 2021-2-24 23:01
我虽然会写,但是不会用vue。
其实挺简单的,但是我不会写vue。
如果能保证运行环境是浏览器的window线程 ...

其实是想在微信小程序里实现的,目前我是在云函数里用mammoth.extractRawText提取到用户上传的docx文档,这是我目前唯一能成功读取word文档的方法了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-2-25 01:27:29 From FishC Mobile | 显示全部楼层
Darth_EF 发表于 2021-2-24 23:01
我虽然会写,但是不会用vue。
其实挺简单的,但是我不会写vue。
如果能保证运行环境是浏览器的window线程 ...

最近在学习用uni-app写微信小程序,所以是vue.js,如果大佬能有更好的实现提取doc文档内容并整理方法那更好啊,我是搜了一圈,自己挨个试完了就这一个方法试成功了…
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-2-25 08:48:22 From FishC Mobile | 显示全部楼层
Darth_EF 发表于 2021-2-24 23:01
我虽然会写,但是不会用vue。
其实挺简单的,但是我不会写vue。
如果能保证运行环境是浏览器的window线程 ...

总结:我不会用 vue
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-2-25 14:00:38 | 显示全部楼层
本帖最后由 Darth_EF 于 2021-2-25 14:14 编辑
_2_ 发表于 2021-2-25 08:48
总结:我不会用 vue


对啊,我不会用vue。因为我大部分时间都在用别的框架。
而且我认为vue在这个问题上没有什么优势。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-2-25 14:17:39 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-2-25 14:19:49 | 显示全部楼层
只要是微信小程序里能实现就行了。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-2-25 16:41:33 | 显示全部楼层
本帖最后由 Darth_EF 于 2021-2-25 16:52 编辑

如果微信没有document和element的话就要写一个xml解释器了,我曾经为我的框架写过一个。不过应该微信是有这些的接口的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-2-26 20:57:35 | 显示全部楼层
Darth_EF 发表于 2021-2-25 16:41
如果微信没有document和element的话就要写一个xml解释器了,我曾经为我的框架写过一个。不过应该微信是有这 ...

感谢大佬,不过微信确实用不了。。。我用for加一堆if试试吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-2-26 21:30:29 | 显示全部楼层
genius_7321 发表于 2021-2-26 20:57
感谢大佬,不过微信确实用不了。。。我用for加一堆if试试吧

报错信息?是因为api的问题的话可以用xml解释器代替
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-2-28 11:58:49 | 显示全部楼层
Darth_EF 发表于 2021-2-26 21:30
报错信息?是因为api的问题的话可以用xml解释器代替

主要是我的基础知识太薄弱了,对document不了解,网上查的是微信小程序的js中不能使用window对象以及document对象
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-3-1 10:55:46 | 显示全部楼层
https://gitee.com/darth_ef/def-web/tree/master/js/ControlLib 这里有个我写的框架,里面有个xml的解释器
使用方法如图
QQ截图20210301105249.png
因为你文本的格式比较简单,把原本用document的东西改成用这个解释器的应该就可以跑了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-3-2 13:58:11 | 显示全部楼层
Darth_EF 发表于 2021-3-1 10:55
https://gitee.com/darth_ef/def-web/tree/master/js/ControlLib 这里有个我写的框架,里面有个xml的解释器 ...

感谢大佬 我研究一下的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-27 09:55

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表