如何区分string中的代码是JS还是CSS代码?

时间:2016-09-11 14:05:30

标签: javascript node.js

我通过简单的POST请求接收代码串,我正在寻找一种聪明的方式(无需运行脚本本身)来区分它是javascript脚本还是css脚本,或者至少是非常肯定的(我是d说55%的可能性是其中之一。

这些不是文件,这些是字符串,所以我没有关于字符串中的代码,没有文件,没有文件扩展,没有标题的任何信息......

你有什么建议/资源吗?

非常感谢。

2 个答案:

答案 0 :(得分:1)

如果这也必须与破坏的代码一起使用,我认为你最好的机会是搜索“典型的CSS”和“典型的JS”的东西,并比较JS的说法和CSS的多少。

JS的典型值是reserved words,它是operators

CSS的典型结构是:[,分隔的选择器] {[;分隔的键值对}}

首先,一些试图评估传递字符串的数量是特定语言的一部分的实用程序。 (非常基本的方法,因此也应该使用破碎的代码)

//returns **kind of** a percentage of how much of the string has been identified as JS/CSS
function evaluateCode(pattern, commentPattern, correctionalFactor){
    correctionalFactor = +correctionalFactor || 1;
    return function(string){
        //removing comments and compacting whitespace.
        //this avoids false hits, and provides a better estimation of how much significant text/code we have (to compute the percentage)
        var t = string.replace(commentPattern || "", "").replace(/\s+/, " ");

        return correctionalFactor * (t.match(pattern) || []).reduce(sumLengths, 0) / t.length;
    }
}
var sumLengths = (acc, match) => acc + match.length;

var evaluateJS = evaluateCode(
    /\b(?:function|return|arguments|this|var|const|let|typeof|instanceof|Array|Object)\b|[+\-*/<>&|=]+|[()\[\]\{\}]/g, 
    /\/\*[\s\S]*\*\/|\/\/[^\n]*/g,
    1.5
);

var evaluateCSS = evaluateCode(
    /[a-z0-9\.#:\[\]=,\s-]+\{(?:\s*[a-z-]+\s*:[^;]+;?)*\s*\}/gi,
    /\/\*[\s\S]*\*\//g
);

用法:

var jsRatio = evaluateJS(string), 
    cssRatio = evaluateCSS(string);

//If there's less than 10% difference between the two estimations, I'd call it "unclear"
if(Math.abs(jsRatio - cssRatio) < .1){
    console.log("result is ambigious, but I tend more towards");
}
console.log("%s (probabilities: css %f%, js %f%)", cssRatio > jsRatio? "css": "js", cssRatio, jsRatio);

我在evaluateJS上使用估计/猜测的“校正因子”1.5,因为正则表达式只匹配部分代码, 而css-regex几乎匹配所有内容。

这一因素仅在结果具有暧昧性时才有意义,通常两种比率之间应存在巨大差距。

编辑:另一个(可能更好)正则表达式搜索CSS:

/[a-z0-9\-]+\s*:[^;{}]+[;}]|(?:[#.]?[a-z]+(?:[#.:\s][a-z0-9-_]+)*\s*[,{])/gi

这只关注键值对和“典型”选择器,包含id和类,而不是整个结构,如果css结构被破坏或者太复杂而不是相当简单的正则表达式,那么这应该是有益的。 / p>

答案 1 :(得分:0)

您可以将返回的字符串包含在阻止其执行的块中(如果它是JavaScript)并查看是否可以解析它。

function isJavaScript(str)
{
    try
    {
        Function('function(){' + str + '}');
        return true; // Looks like valid JS
    }
    catch (error)
    {
        // no valid JavaScript, may be CSS
        return false;
    }
}

我认为这不是100%万无一失,但它可能适用于您的目的。