没有eval的Javascript动态IF正则表达式条件?

时间:2014-05-17 08:16:22

标签: javascript jquery regex filtering eval

我正在向网络应用添加多组复选框过滤(多个无序的复选框列表)并且我试图绕过使用eval(或者我不应该担心这个问题)案件?)。基本上,通过一次AJAX调用来调用数据,我将其存储在一个对象数组中,并且我在不进行额外的AJAX调用的情况下进行实时过滤。选中复选框时,我使用.match(),我基本上将正则表达式创建为数组中的字符串值(k是类别对象属性,例如category1):

filterArgs.push("(data['" + k + "'].join(', ').match(/" + filters[k].join('') + ".+/))");

filters数组在上面的循环中设置,它看起来像这样(v是实际的字符串值 - 类别名称):

filters[k][z] = '(?=.*\\b' + v[z] + '\\b)';

然后我加入了filterArgs:

return filterArgs.join(' && ');

filterArgs当前使用eval传递给if语句条件,如下所示:

if(eval(filter_setup())){

因此,如果if语句为true,则主数据数组中的正确对象将包含在已过滤的数据集中。我可能会切换到jQuery的$ .grep而不是if语句,但我仍然遇到同样的eval问题。有没有其他方法来构建动态正则表达式?它与eval一起正常工作,但我已经阅读了所有文章,说明如何" evil"它是。 if语句条件最终看起来如下(在第一组中检查了2个方框,在另一个组中检查了1个):

(data['type'].join(', ').match(/(?=.*\bRestaurant\b)(?=.*\bBar\b).+/)) && (data['state'].join(', ').match(/(?=.*\bWashington\b).+/))

2 个答案:

答案 0 :(得分:1)

尽可能避免使用eval。在这种情况下,它绝对没有必要。

在需要时存储filter对象并定义如下内容:

function checkFilters(data, filters) {
    for (var k in filters) {
        if (!(new RegExp(filters[k].join("")).test(data[k])))
            return false;
    return true;
}

所以你可以像这样使用它:

if (checkFilters(data, filters)) {
    ...
}

顺便说一句,使用构造函数创建RegExp对象非常昂贵。如果您需要更高的速度,可以预编译过滤器并保留它们而不是一系列条件:

filters[k] = new RegExp(filters[k].join(""));

此外,正如Dave所说,根据您的数据,您可能需要逃避过滤器:

filters[k][z] = '(?=.*\\b'
        + v[z].replace(/([\^\$\/\.\*\+\?\|\(\)\[\]\{\}\\])/g, "\\$1")
        + '\\b)';

答案 1 :(得分:0)

您可以推送一个函数,而不是推送表达式:

 filterArgs.push(function(k){
   var re = new RegExp(filters[k].join('') + ".+");
   return function(data){
     return data[k].join(', ').match(re);
   }
 });

现在您可以执行函数而不是评估字符串:

 for(var cond = true, i = 0; cond && i < filterArgs.length; i++) {
   cond &= filterArgs[i](data);
 }