[英]Evaluate a boolean condition stored as a string
I have several thousand entries in a database that were scraped from a website. 我从网站上抓取的数据库中有数千个条目。 They are strings which list conditions which must be met. 它们是列出必须满足的条件的字符串。 For example: "(Thing1 and Thing2) or (Thing3 and Thing4)"
例如: "(Thing1 and Thing2) or (Thing3 and Thing4)"
I would like a user to enter a list of conditions they have, and then check them against the database. 我希望用户输入他们具有的条件列表,然后对照数据库进行检查。 Due to the fact that these strings come from a trusted site, and are so close to valid boolean conditions already I'm tempted to put them in an eval()
statement. 由于这些字符串来自受信任的站点,并且已经非常接近有效的布尔条件,因此我很想将它们放在eval()
语句中。 I could parse the string, find the conditions, check if they are true, and replace them with 1 or 0. Then replace (and, or) with (&&, ||). 我可以解析字符串,找到条件,检查条件是否正确,然后将其替换为1或0。然后将(and,or)替换为(&&,||)。 Then I would check to make sure everything at that point is one of: space, 1, 0, &, |, (, or ). 然后,我将检查以确保此时的所有内容都是以下之一:space,1、0,&,|,(或)。 If not, log the error in some way. 如果不是,请以某种方式记录错误。 If it is just those characters do: 如果只是这些字符,请执行以下操作:
eval("Boolean((1 && 0) || (0 && 0))")
I realize eval()
is generally a bad idea, so I'm open to other ideas. 我意识到eval()
通常不是一个好主意,因此我欢迎其他想法。 However, in this case I feel the security is increased if I check for just those characters before running the eval, and since the input is data scraped from a trusted site. 但是,在这种情况下,如果我在运行评估之前仅检查那些字符,并且输入是从受信任的站点抓取的数据,则我认为安全性得到了提高。
I'm planning on doing this in javascript, but could also do it in PHP on the server. 我打算在javascript中执行此操作,但也可以在服务器上的PHP中执行此操作。
If you really want to avoid eval() at all cost, you could use something like this: 如果您确实想不惜一切代价避免使用eval(),则可以使用如下代码:
function evalBoolean(str) { while (str.length > 1) { str = str.replace(/0 && 0|0 && 1|1 && 0|0 \\|\\| 0|\\(0\\)/g, "0"); str = str.replace(/1 && 1|0 \\|\\| 1|1 \\|\\| 0|1 \\|\\| 1|\\(1\\)/g, "1"); } return (str == "1"); } alert(evalBoolean("((0 && 1) || (1 && 1))")); alert(evalBoolean("(((0 || 1) && (0 || 0)) && ((1 || 1) || 0))"));
If you think there could be malformed input, use this safer version which returns undefined if it can't resolve the expression. 如果您认为可能存在格式错误的输入,请使用此更安全的版本,如果无法解析该表达式,则返回undefined。
function evalBoolean(str) { var len; while (str.length > 1) { if (str.length == len) return; else len = str.length; str = str.replace(/0\\s*&&\\s*0|0\\s*&&\\s*1|1\\s*&&\\s*0|0\\s*\\|\\|\\s*0|\\(\\s*0\\s*\\)|\\s*0\\s*/g, "0"); str = str.replace(/1\\s*&&\\s*1|0\\s*\\|\\|\\s*1|1\\s*\\|\\|\\s*0|1\\s*\\|\\|\\s*1|\\(\\s*1\\s*\\)|\\s*1\\s*/g, "1"); } return (str == "1"); } alert(evalBoolean(" (( (0|| 1) &&(0 || 0) )&& ( (1||1) ||0))")); alert(evalBoolean("((1 && 0) && 1 )) ( && 1"));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.