- 拆分对经营者的字符串
- 漫步生成的拆分字符串:
- 验证运营商
- 转换
,
到||
- 可选验证名称
- 与
true
更换名称(如果它在阵列中)或false
(如果不是)
- 归队结果转换成字符串再次
- 贯穿
eval
的结果(因为你现在知道它只有你列入白名单运营商和文本true
或false
)
这里有一个快速验证的概念:Live Copy | Live Source
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Expression Thingy</title>
<style>
.good {
color: green;
}
.bad {
color: #d22;
}
</style>
</head>
<body>
<script>
(function() {
var array = ["red", "blue", "neon", "black", "orange"];
var tests = [
{expr: "red&&blue", expect: true},
{expr: "blue&&white", expect: false},
{expr: "red,white", expect: true},
{expr: "(red&&blue),(red&&white)", expect: true},
{expr: "(red&&blue)&&(red&&white)", expect: false},
{expr: "(red&&blue)&&(red&&neon)", expect: true},
{expr: "(red+blue)&&(red!neon)", expectInvalid: true}
];
var data;
// Turn data into an object with named properties, to make lookups
// faster
data = {};
array.forEach(function(entry) {
data[entry] = true;
});
// Run the tests
tests.forEach(runTest);
function runTest(test) {
var parts, invalid = false;
// Get an array of tokens: We'll get `(`, `)`, `,`, `&&`, whitespace, or a name in each array slot
parts = test.expr.match(/&&|,|\(|\)|\s+|[^()&,]+/g);
// Validate the operators and turn the names into "true" or "false"
parts.forEach(function(part, index) {
switch (part) {
case ",":
// Valid operator, replace with ||
parts[index] = "||";
break;
case "&&":
case "(":
case ")":
// Valid operator
break;
default:
// Name or whitespace
if (!part.replace(/\s+/g, "")) {
// Whitespace
}
else {
// Name, validate it -- obviously apply whatever rule works
// for your data, the rule below allows A-Z, $, and _ in
// the first position and those plus digits in subsequent
// positions.
if (!/^[A-Za-z$_][A-Za-z0-9$_]*$/.test(part)) {
// Invalid
display("Invalid name: " + part, test.expectInvalid);
invalid = true;
}
else {
// Valid, replace it
parts[index] = data[part] ? "true" : "false";
}
}
break;
}
});
if (!invalid) {
// Now we know parts only has valid stuff we can trust in it, rejoin
// and eval it
result = !!eval(parts.join(""));
display(test.expr + ": Got " + result + ", expected " + test.expect, result === test.expect);
}
}
function display(msg, good) {
var p = document.createElement('p');
p.innerHTML = String(msg);
if (typeof good !== "undefined") {
p.className = good ? "good" : "bad";
}
document.body.appendChild(p);
}
})();
</script>
</body>
</html>
你可能想按摩验证规则至少位。
老答案,这主要是假设你能信任的输入:
可以很容易地把这些投入有效的JavaScript表达式。此后,您可以:
使用解析器别人已经写的,like this one(在this blog post细节)(即一个似乎不支持&&
和||
,虽然也许你可以把它扩展到)或
将数组转换为对象属性并使用eval
。 从不信任eval
对不安全或不能安全的输入使得安全。但是,如果输入是安全的或可以安全的,eval
是好的。
假设阵列中的值是有效的JavaScript标识符,则可以简单地通过改变,
到||
把这些表达式转化为有效的JavaScript表达式:
str = str.replace(/,/g, "||");
同样,这原来该数组到对象与那些命名的属性:
var obj = {};
data.forEach(function(entry) {
obj[entry] = true;
});
...你大概会传入表达式评估器。
如果你打算在eval
路线,你必须做字符串多一点准备,把"(red&&blue),(red&&white)"
到'(obj["red"]&&obj["blue"])||(obj["red"]&&obj["white"])'
,像这样:
str = str.replace(/,/g, "||").replace(/\b([a-zA-Z0-9_]+)\b/g, 'obj["$1"]');
使用表达式我不会做榜样评估者库,但这里是与eval
的基础知识:Live Copy | Live Source
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Expression Thingy</title>
<style>
.good {
color: green;
}
.bad {
color: #d22;
}
</style>
</head>
<body>
<script>
(function() {
var data = ["red", "blue", "neon", "black", "orange"];
var tests = [
{expr: "red&&blue", expect: true},
{expr: "blue&&white", expect: false},
{expr: "red,white", expect: true},
{expr: "(red&&blue),(red&&white)", expect: true},
{expr: "(red&&blue)&&(red&&white)", expect: false},
{expr: "(red&&blue)&&(red&&neon)", expect: true}
];
var obj;
// Turn data into an object with named properties
obj = {};
data.forEach(function(entry) {
obj[entry] = true;
});
// Turn the expressions into eval strings
tests.forEach(createEvalString);
// Run the tests
tests.forEach(runTest);
function createEvalString(test) {
test.evalStr = test.expr.replace(/,/g, "||").replace(/\b([a-zA-Z0-9_]+)\b/g, 'obj["$1"]');
}
function runTest(test) {
var result;
display(test.evalStr);
result = !!eval(test.evalStr); // Relies on us closing over `obj`
display(test.expr + ": Got " + result + ", expected " + test.expect, result === test.expect);
}
function display(msg, good) {
var p = document.createElement('p');
p.innerHTML = String(msg);
if (typeof good !== "undefined") {
p.className = good ? "good" : "bad";
}
document.body.appendChild(p);
}
})();
</script>
</body>
</html>
这只是一个起点。首先,您需要仔细检查琴弦,然后再转换它们并使用eval
。
Javascript中有相当多的[parser generators](http://stackoverflow.com/questions/6211111/javascript-parser-generator)。 – georg