Javascript 如何将包含多个js语句的字符串拆分为一个字符串数组,每个字符串包含一个语句?

Javascript 如何将包含多个js语句的字符串拆分为一个字符串数组,每个字符串包含一个语句?,javascript,parsing,Javascript,Parsing,我有一个字符串,其中包含许多用“;”分隔的JavaScript语句 我需要将其拆分为一个字符串数组,每个字符串包含一个单独的命令 我不能简单地用“;”作为分隔符使用字符串拆分函数,因为“;”也存在于字符串中的其他命令中 如何将包含多个js语句的字符串拆分为一个字符串数组,每个字符串包含一个单独的命令? 例如,我可以有如下内容: $('_32123').innerHTML="<div style=\"font-size:11px;margin-right:15px;margin-

我有一个字符串,其中包含许多用“;”分隔的JavaScript语句
我需要将其拆分为一个字符串数组,每个字符串包含一个单独的命令

我不能简单地用“;”作为分隔符使用字符串拆分函数,因为“;”也存在于字符串中的其他命令中

如何将包含多个js语句的字符串拆分为一个字符串数组,每个字符串包含一个单独的命令?

例如,我可以有如下内容:

    $('_32123').innerHTML="<div  style=\"font-size:11px;margin-right:15px;margin-
bottom:5px;text-align:right;\" id=\"_134607\"   noprint='no' noprintoverflow='no'>
    </div>";document.onkeydown = function(event) { if (event.ctrlKey && 
event.keyCode == 89) Event(3160,'Refresh',{ q:'' }); };
$(''u 32123')。innerHTML=”
";document.onkeydown=函数(事件){if(event.ctrlKey&&
event.keyCode==89)事件(3160,'Refresh',{q:'});};

是否有一个库或其他东西可以提供此功能,或者如何解决此问题?

正则表达式太简单,无法将JavaScript代码拆分为语句。虽然这可以用于简单的事情,但JavaScript字符串、JavaScript正则表达式和注释使其更加复杂。此外,JavaScript构造不一定以分号结尾。考虑这一点:

if (foo) { throw "bar"; }
虽然
抛出“bar”
以分号结尾,不清楚您是要捕获整个if语句及其主体,还是只捕获
抛出部分。
除此之外,JavaScript语句也可能以换行符结尾。以下是两条有效的JavaScript语句,但没有用分号分隔:

a = 1
b = 2
为了处理所有这些复杂的规则,您需要一个有语言意识的解析器。有几种JavaScript解析框架,您必须选择适合您的解析器框架

下面是使用标记化语句的示例。在使用npm install acorn安装acorn后,我在nodejs中运行了以下代码:

var code = "$('_32123').innerHTML=\"<div style=\\\"font-size:11px;margin-right:15px;margin-bottom:5px;text-align:right;\\\" id=\\\"_134607\\\"   noprint='no' noprintoverflow='no'></div>\";document.onkeydown = function(event) { if (event.ctrlKey && event.keyCode == 89) Event(3160,'Refresh',{ q:'' }); };";

var acorn = require("acorn");
var tokens = acorn.parse(code);

tokens.body.forEach(function(token) {
  console.log("statement: ", code.substr(token.start, token.end - token.start));
});
var code=“$(''u 32123')。innerHTML=\“\”;document.onkeydown=函数(事件){if(event.ctrlKey&&event.keyCode==89)事件(3160,'Refresh',{q:'});};
var acorn=要求(“acorn”);
var tokens=acorn.parse(代码);
tokens.body.forEach(函数(令牌){
log(“语句:”,code.substr(token.start,token.end-token.start));
});
这将打印示例代码中的两个顶级语句

请注意,您提供的示例JavaScript代码只有两个顶级语句(两个赋值表达式),但总共有两个以上的语句。例如,还有一个函数声明和一个if语句。这些语句是两个顶级语句的子语句

如果要单独捕获所有这些语句(顶级语句和子语句),则需要遍历解析器生成的抽象语法树,并递归到子类中。递归也是必要的,因为JavaScript允许嵌套结构(控制结构、函数)

这将很容易变得有点复杂,因为您必须处理不同的subtoken类型。下面是一个仅处理几种类型的示例实现,演示了如何遍历AST:

var code = "$('_32123').innerHTML=\"<div style=\\\"font-size:11px;margin-right:15px;margin-bottom:5px;text-align:right;\\\" id=\\\"_134607\\\"   noprint='no' noprintoverflow='no'></div>\";document.onkeydown = function(event) { if (event.ctrlKey && event.keyCode == 89) Event(3160,'Refresh',{ q:'' }); };";

var acorn = require("acorn");
var tokens = acorn.parse(code);

function recursiveDump(token, level) {
  var pad = Array(level).join("  "); 
  console.log(pad + "- token");
  console.log(pad + "  - type: " + token.type);
  console.log(pad + "  - code: " + code.substr(token.start, token.end - token.start));

  if (token.type === 'ExpressionStatement') {
    if (token.expression.left) {
      console.log(pad + "  - children:");
      recursiveDump(token.expression.left, level + 3);
      recursiveDump(token.expression.right, level + 3);
      console.log(); 
    }
  }
  else if (token.type === 'IfStatement') {
    console.log(pad + "  - children:");
    recursiveDump(token.test, level + 3);
    recursiveDump(token.consequent, level + 3);
    if (token.alternate !== null) {
      recursiveDump(token.alternate, level + 3);
    }
    console.log();
  }
  else if (token.hasOwnProperty("body")) {
    console.log(pad + "  - children:");
    var body = token.body;
    if (! Array.isArray(body) && body.hasOwnProperty("body")) {
      body = body.body;
    }

    body.forEach(function(token) {
      recursiveDump(token, level + 3);
    });
    console.log();
  }
}

tokens.body.forEach(function(token) {
  recursiveDump(token, 0);
});
var code=“$(''u 32123')。innerHTML=\“\”;document.onkeydown=函数(事件){if(event.ctrlKey&&event.keyCode==89)事件(3160,'Refresh',{q:'});};
var acorn=要求(“acorn”);
var tokens=acorn.parse(代码);
函数递归转储(令牌,级别){
var pad=数组(级别).join(“”);
console.log(pad+“-token”);
console.log(pad+“-type:”+token.type);
log(pad+“-code:”+code.substr(token.start,token.end-token.start));
if(token.type==='ExpressionStatement'){
if(token.expression.left){
console.log(pad+“-子项:”);
递归转储(token.expression.left,级别+3);
递归转储(token.expression.right,级别+3);
console.log();
}
}
else if(token.type==='IfStatement'){
console.log(pad+“-子项:”);
递归转储(token.test,级别+3);
递归转储(token.continued,级别+3);
if(token.alternate!==null){
递归转储(token.alternate,级别+3);
}
console.log();
}
else if(token.hasOwnProperty(“body”)){
console.log(pad+“-子项:”);
var body=token.body;
if(!Array.isArray(body)和&body.hasOwnProperty(“body”)){
body=body.body;
}
body.forEach(函数(令牌){
递归转储(令牌,级别+3);
});
console.log();
}
}
tokens.body.forEach(函数(令牌){
递归转储(令牌,0);
});

这只是一个简单的例子,说明了一般如何处理子项。如果只需要处理顶级语句,则可以保存所有这些工作

正则表达式太简单,无法将JavaScript代码拆分为语句。虽然这可以用于简单的事情,但JavaScript字符串、JavaScript正则表达式和注释使其更加复杂。此外,JavaScript构造不一定以分号结尾。考虑这一点:

if (foo) { throw "bar"; }
虽然
抛出“bar”
以分号结尾,不清楚您是要捕获整个if语句及其主体,还是只捕获
抛出部分。
除此之外,JavaScript语句也可能以换行符结尾。以下是两条有效的JavaScript语句,但没有用分号分隔:

a = 1
b = 2
为了处理所有这些复杂的规则,您需要一个有语言意识的解析器。有几种JavaScript解析框架,您必须选择适合您的解析器框架

下面是使用标记化语句的示例。在使用npm install acorn安装acorn后,我在nodejs中运行了以下代码:

var code = "$('_32123').innerHTML=\"<div style=\\\"font-size:11px;margin-right:15px;margin-bottom:5px;text-align:right;\\\" id=\\\"_134607\\\"   noprint='no' noprintoverflow='no'></div>\";document.onkeydown = function(event) { if (event.ctrlKey && event.keyCode == 89) Event(3160,'Refresh',{ q:'' }); };";

var acorn = require("acorn");
var tokens = acorn.parse(code);

tokens.body.forEach(function(token) {
  console.log("statement: ", code.substr(token.start, token.end - token.start));
});
var code=“$(''u 32123')。innerHTML=\'”document.onkeydown=函数(事件){if(event.ctrlKey&&event.keyCode==89)事件(3160,'Refresh',{q:'});}