如何区分字符串中的代码是JS还是CSS代码

How to distinguish if code in string is a piece of JS or CSS code?

本文关键字:代码 JS 还是 CSS 何区 字符串      更新时间:2023-09-26

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

这些不是文件,这些是字符串,所以我没有关于字符串中的代码的任何信息,没有文件,没有文件ext,没有头…

你有什么建议/资源吗?

谢谢。

如果这也必须与破碎的代码一起工作,我认为你最好的机会是搜索"典型的CSS"answers"典型的JS"的东西,并比较JS和CSS的比例。

典型的JS是它的保留字和操作符。

典型的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结构被破坏或对于相当简单的正则表达式来说过于复杂,这应该是有益的。

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

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

我不认为这是百分之百的万无一失,但它可能对你的目的。