gpt4 book ai didi

javascript - JS 将 OData $filter 字符串解析为对象结构

转载 作者:行者123 更新时间:2023-11-30 05:31:12 25 4
gpt4 key购买 nike

我正在尝试将 OData 过滤器字符串转换为表示过滤器的对象。下面是我想要转换的复杂(非现实)OData 过滤器的示例。

substringof('v', p1) or (p2 gt 5 and p3 eq 'v v' and (p4 eq false or startswith(p5.expand, 'v'))) or (p6 eq 6 and p7 eq 7)

使用下面的正则表达式和函数,我将其分为两部分:一个过滤器部分数组和一个字符串,每个过滤器部分由数组中的索引替换。

var conditionMatcher = new RegExp("(substringof\\(.+?\\)|startswith\\(.+?\\)|endswith\\(.+?\\)|[\\w\\.]+?\\s(?:eq|ne|gt|ge|lt|le)\\s(?:\\w+|\\'.+?\\'))", "g");
var filters = predicateString.match(conditionMatcher);
var i = 0;
var simpleString = predicateString.replace(conditionMatcher, function () {
return i++;
});

// simpleString =
0 or (1 and 2 and (3 or 4)) or (5 and 6)

目标是将字符串转换成如下形式:

{
op: "or",
filters: [
0,
{
op: "and",
filters: [
1,
2,
{
op: "or",
filters: [
3,
4
]
}
]
},
{
op: "and",
filters: [
5,
6
]
}
]
}

我只是不确定如何到达这里。如果有人有想法,在我继续研究解决方案的过程中,将不胜感激。

最佳答案

到目前为止,我的解决方案是解析字符串以查找第一个右括号及其匹配的左括号,从组构建过滤器,用过滤器的索引替换组并向外工作。

// This array contains the filter parts extracted from the code in my question  
var filters = [...];
var filterString = "0 or (1 and 2 and (3 or 4)) or (5 and 6)";

var groupString;
var groupFilter = null;
var testNextLevel = true;

while (testNextLevel) {
var closeParenthesisIndex = filterString.indexOf(')');
if (closeParenthesisIndex !== -1) {
var openParenthesisIndex = filterString.lastIndexOf('(', closeParenthesisIndex);

// Extract the string between the first deepest set of parenthesis
groupString = filterString.substring(openParenthesisIndex + 1, closeParenthesisIndex);

// Modify the filter string replacing the contents of the group string in addition to the parenthesis with the length of the filters array (which will be the index of the filter object that we push)
filterString = filterString.substring(0, openParenthesisIndex) + filters.length + filterString.substring(closeParenthesisIndex + 1);
} else {

// There are no more parenthesis groups
groupString = filterString;
testNextLevel = false;
}

// If the group uses both 'and' and 'or' then return null as an invalid filter string.
if (groupString.indexOf('and') >= 0 && groupString.indexOf('or') >= 0) {
return null;
}

// Get the group indexes out of the group string
var groupFilterIndexes = groupString.match(/[0-9]+/g);
var groupFilters = [];

// Create an array with each of the filters who's index matches the group indexes
for (i = 0; i < groupFilterIndexes.length; i++) {
groupFilters.push(filters[Number(groupFilterIndexes[i])]);
}
var op = groupString.indexOf('or') >= 0 ? 'or' : 'and';

// Create the filter object and push it onto the filters array
groupFilter = { op: op, filters: groupFilters };
filters.push(groupFilter);
}

return groupFilter;

检查每个级别时,将构建过滤器对象并将匹配的索引推送到过滤器对象中。然后将过滤器对象插入过滤器数组,并将 filterString 的当前部分替换为过滤器对象的索引。序列看起来像这样:

// First Level
starting filterString: "0 or (1 and 2 and (3 or 4)) or (5 and 6)"
starting filters.length: 7
groupString: "3 or 4"
filters[7] = { op: "or", filters: [filters[3], filters[4]] }
filterString after extraction: "0 or (1 and 2 and 7) or (5 and 6)"
filters.length: 8

// Second Level
starting filterString: "0 or (1 and 2 and 7) or (5 and 6)"
starting filters.length: 8
groupString: "1 and 2 and 7"
filters[8] = { op: "and", filters: [filters[1], filters[2], filters[7]] }
filterString after extraction: "0 or 8 or (5 and 6)"
filters.length: 9

// Third Level
starting filterString: "0 or 8 or (5 and 6)"
starting filters.length: 9
groupString: "5 and 6"
filters[9] = { op: "and", filters: [filters[5], filters[6]] }
filterString after extraction: "0 or 8 or 9"
filters.length: 10

// Final Level
starting filterString: "0 or 8 or 9"
starting filters.length: 10
groupString: "0 or 8 or 9"
filters[10] = { op: "or", filters: [filters[0], filters[8], filters[9]] }
filters.length: 11

// Return filters[10]

关于javascript - JS 将 OData $filter 字符串解析为对象结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26876497/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com