genius_7321 发表于 2021-2-23 01:09:58

如何将字符串按特定规律转换成json

本帖最后由 genius_7321 于 2021-2-23 01:12 编辑

希望能够用vue.js实现如下效果:
给定字符串:
<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>

原始字符串是这样的:


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


期待输出如下对象数组:

Darth_EF 发表于 2021-2-23 01:09:59

本帖最后由 Darth_EF 于 2021-2-25 16:52 编辑


            // 把字符串转换成 node 数组
            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>"
            var temp=document.createElement("div");
            temp.innerHTML=str;
            var nodeList=temp.children;

            class Cr{
                /**
               * @param {Array<CrNode>} CrNodes
               */
                constructor(CrNodes){
                  this.crs=CrNodes;
                  this.qObjs=[];
                }
                /**
               * @param {Array<Element>} elements
               * @returns {Array<QOBJ>} 返回 QOBJ 数组
               */
                loadElement(elements){
                  this.qObjs=[];
                  for(var i=0;i<elements.length;++i){
                        for(var j=this.crs.length-1;j>=0;--j){
                            if(this.crs.regexp.test(elements.innerHTML)){
                              this.crs.callback.call(this,elements.innerHTML);
                              this.crs=this.crs.next;
                              j=this.crs.length-1;
                              break;
                            }
                        }
                  }
                  for(var i=this.qObjs.length-1;i>=0;--i){
                        if(!this.qObjs.QBType){
                            var tempStr=this.qObjs.answer,typeStr;
                            if(tempStr.length>1){
                              if((/^\w+/).test(tempStr)){
                                    typeStr="MC";
                              }else{
                                    typeStr="JD";
                                    if(this.qObjs.answer.indexOf("正确")!=-1){
                                        this.qObjs.answer="A";
                                    }else{
                                        this.qObjs.answer="B";
                                    }
                              }
                            }else{
                              typeStr="SC";
                            }
                            this.qObjs.QBType=typeStr;
                        }
                  }
                  return this.qObjs;
                }
            }
            class CrNode{
                /**
               * @param {RegExp} regexp       匹配字符串的正则表达式
               * @param {Function} callback   callback.call(Cr,elements.innerHTML);
               * @param {Array<RegExp>} next匹配到之后修改当前的匹配
               */
                constructor(regexp,callback,next){
                  this.regexp=regexp;
                  this.next=next;
                  this.callback=callback;
                }
            }
            class QOBJ{
                constructor(){
                  this.id=0;
                  this.title="";
                  this.answer="";
                  this.analysis="";
                  this.QBType="";
                }
                /**
               * @param {String} str
               */
                addOption(str){
                  var i=0,tempString="option"+String.fromCharCode(i+65);
                  while(this){
                        ++i;
                        tempString="option"+String.fromCharCode(i+65);
                  }
                  this=str;
                }
                getOptionLength(){
                  var i=0,tempString="option"+String.fromCharCode(i+65);
                  while(this){
                        ++i;
                        tempString="option"+String.fromCharCode(i+65);
                  }
                  return i;
                }
            }

            var titleCr=new CrNode(/^+\.[.\n\r]*/,function(str){
                var i=this.qObjs.length-1;
                i=this.qObjs.push(new QOBJ());
                var temp=str.match((/[\((]+([\w正确错误]+)[\))]+/));
                if(temp){
                  this.qObjs.answer=temp;
                }
                this.qObjs.title=str.slice(str.indexOf('.')+1);
                this.qObjs.id=parseInt(str.slice(0,str.indexOf('.')));
            });
            var optionCr=new CrNode(/^|+[::][.\n\r]*/,function(str){
                var i=this.qObjs.length-1;
                this.qObjs.addOption(str.slice(str.indexOf(/[::]/)+1));
            });
            var optionBoolCr=new CrNode(/^[正确 错误]+/,function(str){
                var i=this.qObjs.length-1;
                this.qObjs.addOption("正确");
                this.qObjs.addOption("错误");
                this.qObjs.QBType="JD"
            });
            var answerCr=new CrNode(/^正确答案为[::][.\n\r]*/,function(str){
                var i=this.qObjs.length-1;
                var tempStr=str.slice("正确答案为:".length),typeStr="";

            });
            var analysisCR=new CrNode(/^解析[::][.\n\r]*/,function(str){
                var i=this.qObjs.length-1;
                this.qObjs.analysis=str.slice("解析:".length);
            });
            titleCr.next=;
            optionCr.next=;
            optionBoolCr.next=;
            answerCr.next=;
            analysisCR.next=;
            
            var d=new Cr();
            var c=d.loadElement(nodeList);

            console.log(JSON.stringify(c));


Darth_EF 发表于 2021-2-24 23:01:22

本帖最后由 Darth_EF 于 2021-2-25 16:47 编辑

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

如果要的话,我可以用js给你写; 而且请告诉我你的运行环境是什么。

genius_7321 发表于 2021-2-25 01:10:07

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

其实是想在微信小程序里实现的,目前我是在云函数里用mammoth.extractRawText提取到用户上传的docx文档,这是我目前唯一能成功读取word文档的方法了{:10_245:}

genius_7321 发表于 2021-2-25 01:27:29

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

最近在学习用uni-app写微信小程序,所以是vue.js,如果大佬能有更好的实现提取doc文档内容并整理方法那更好啊,我是搜了一圈,自己挨个试完了就这一个方法试成功了…

_2_ 发表于 2021-2-25 08:48:22

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

总结:我不会用 vue{:10_256:}

Darth_EF 发表于 2021-2-25 14:00:38

本帖最后由 Darth_EF 于 2021-2-25 14:14 编辑

_2_ 发表于 2021-2-25 08:48
总结:我不会用 vue

对啊,我不会用vue。因为我大部分时间都在用别的框架。
而且我认为vue在这个问题上没有什么优势。

3553107168 发表于 2021-2-25 14:17:39

{:5_108:}

genius_7321 发表于 2021-2-25 14:19:49

只要是微信小程序里能实现就行了。。。{:9_237:}

Darth_EF 发表于 2021-2-25 16:41:33

本帖最后由 Darth_EF 于 2021-2-25 16:52 编辑

如果微信没有document和element的话就要写一个xml解释器了,我曾经为我的框架写过一个。不过应该微信是有这些的接口的。

genius_7321 发表于 2021-2-26 20:57:35

Darth_EF 发表于 2021-2-25 16:41
如果微信没有document和element的话就要写一个xml解释器了,我曾经为我的框架写过一个。不过应该微信是有这 ...

感谢大佬,不过微信确实用不了。。。我用for加一堆if试试吧

Darth_EF 发表于 2021-2-26 21:30:29

genius_7321 发表于 2021-2-26 20:57
感谢大佬,不过微信确实用不了。。。我用for加一堆if试试吧

报错信息?是因为api的问题的话可以用xml解释器代替

genius_7321 发表于 2021-2-28 11:58:49

Darth_EF 发表于 2021-2-26 21:30
报错信息?是因为api的问题的话可以用xml解释器代替

主要是我的基础知识太薄弱了,对document不了解,网上查的是微信小程序的js中不能使用window对象以及document对象

Darth_EF 发表于 2021-3-1 10:55:46

https://gitee.com/darth_ef/def-web/tree/master/js/ControlLib 这里有个我写的框架,里面有个xml的解释器
使用方法如图

因为你文本的格式比较简单,把原本用document的东西改成用这个解释器的应该就可以跑了

genius_7321 发表于 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的解释器 ...

感谢大佬 我研究一下的
页: [1]
查看完整版本: 如何将字符串按特定规律转换成json