Javascript 将字符串中的数字替换为对象
我有两个变量Javascript 将字符串中的数字替换为对象,javascript,node.js,string,object,data-structures,Javascript,Node.js,String,Object,Data Structures,我有两个变量 var sequence = '(1 AND 2) OR (2 AND 3)' var filters =[{ "name": "title", "opr": "=", "value": "My Post", "sid": "1" }, { "name": "content", "opr": "like", "value": "Hello",
var sequence = '(1 AND 2) OR (2 AND 3)'
var filters =[{
"name": "title",
"opr": "=",
"value": "My Post",
"sid": "1"
},
{
"name": "content",
"opr": "like",
"value": "Hello",
"sid": "2"
},
{
"name": "id",
"opr": "gt",
"value": "100",
"sid": "3"
}
]
现在我正在寻找替换序列并将其转换为如下格式
var output = {
"OR": [{
"AND": [{
"title": "My Post"
},
{
"content": {
"like": "Hello"
}
}
]
},
{
"AND": [{
"content": {
"like": "Hello"
}
},
{
"id": {
"gt": "1000"
}
}
]
}
]
}
}
对于序列字符串,每个数字表示对象数组中的sid
对于对象数组中的opr,如果opr等于“=”,则应创建简单的键值对对象,如
{"title": "My Post"}
对于其他运营商,它应该创建类似的
{"content": {"like": "Hello"}}
您想要创建一个解析器 您的用例可能会有所不同,并且会改变您想要进行的权衡,但是这里有一个简单的实现,它完成了您上面概述的内容
const SEQUENCE=“(1和2)或(2和3)”;
常数过滤器=[{
姓名:“职务”,
opr:“=”,
值:“我的帖子”,
希德:“1”
},
{
名称:“内容”,
opr:“像”,
值:“你好”,
希德:“2”
},
{
姓名:“id”,
opr:“gt”,
值:“1000”,
希德:“3”
}
];
const result=编译器(序列、过滤器);
控制台日志(结果);
函数编译器(序列、过滤器){
让标记=_标记器(序列);
设ast=_解析器(令牌);
设newAst=_变压器(ast);
让输出=_生成器(newAst,filters,{});
返回输出;
}
//////////////////////////
函数_标记器(输入){
设电流=0;
让令牌=[];
设expr=/^[(].[)]$/;
让我们来看看斯帕伦斯;
让parenCounter;
[]forEach.call(输入、函数(字符、索引){
如果(char=='(')parenCounter=(parenCounter==null)?1:parenCounter+1;
if(char==')--parenCounter;
如果(parenCounter==0&&index!=input.length-1)needsParens=true;
});
如果(!expr.test(input)| | needsParens)input=“(“+input+”)”;
while(电流<输入长度){
让char=输入[当前];
如果(字符==='('){
代币({
键入:“paren”,
值:'(',
});
电流++;
继续;
}
如果(字符==')'){
代币({
键入:“paren”,
值:')',
});
电流++;
继续;
}
让空白=/\s/;
if(空格测试(字符)){
电流++;
继续;
}
设数字=/[0-9]/;
if(数字测试(字符)){
让值=“”;
while(数字测试(字符)){
值+=字符;
字符=输入[++当前];
}
代币({
键入:“编号”,
价值
});
继续;
}
让字母=/[A-Z]/i;
if(字母测试(字符)){
让值=“”;
while(字母测试(字符)){
值+=字符;
字符=输入[++当前];
}
代币({
键入:“名称”,
价值
});
继续;
}
抛出新的TypeError('未知标记:'+字符);
}
归还代币;
}
//////////////////////////
//////////////////////////
函数_解析器(令牌){
设电流=0;
函数walk(){
let token=tokens[当前];
if(token.type==='number'){
电流++;
返回{
类型:'NumberTerral',
value:token.value,
};
}
if(token.type==='name'){
电流++;
返回{
键入:“NameLiteral”,
value:token.value,
};
}
if(token.type=='paren'&&token.value=='(')){
令牌=令牌[++当前];
让节点={
键入:“表达式”,
参数:[],
};
而((token.type!=='paren')| |(token.type==='paren'和&token.value!==')){
node.params.push(walk());
令牌=令牌[当前];
}
电流++;
返回节点;
}
抛出新类型错误(token.type);
}
设ast={
键入:“程序”,
正文:[],
};
while(当前{
_遍历节点(子节点、父节点);
});
}
函数_transverseNode(节点,父节点){
let methods=visitor[node.type];
if(methods&&methods.enter)methods.enter(节点、父节点);
开关(节点类型){
案例“程序”:
_Traversarray(node.body,node);
打破
“表达式”一案:
_Traversarray(node.params,node);
打破
案例“第三方”:
大小写“NameLiteral”:
打破
违约:
抛出新类型错误(node.type);
}
if(methods&&methods.exit)methods.exit(节点、父节点);
}
_遍历节点(ast,null);
}
//////////////////////////
//////////////////////////
功能变压器(ast){
设newAst={
键入:“程序”,
正文:[],
};
ast.\u context=newAst.body;
_遍历器(ast{
数目:{
输入(节点、父节点){
父项。\u context.push({
类型:'NumberTerral',
值:node.value,
});
},
},
名称文字:{
输入(节点、父节点){
parent.\u expression.bool=node.value;
},
},
表达方式:{
输入(节点、父节点){
let表达式={
键入:“表达式”,
参数:[],
};
节点。_表达式=表达式;
节点。_context=expression.arguments;
父._context.push(表达式);
},
}
});
返回newAst;
}
//////////////////////////
//////////////////////////
函数生成器(节点、过滤器、映射){
if(filters)filters.forEach(filter=>map[filter.sid]=filter);
开关(节点类型){
案例“程序”:
返回JSON.parse(_生成器(node.body[0],null,map));
“表达式”一案:
返回“{”+node.bool+”:['+node.arguments.map(arg=>_生成器(arg,null,map))+']}”;
案例“第三方”:
让filter=map[node.value];
if(filter.opr=='=')返回“{”+filter.name+'”:“+filter.value+'”}”;
返回“{”+filter.name+”:{”+filter.opr+”:“+filter.value+”}}”;
违约:
抛出新类型错误(node.type);
}
}
//////////////////////////
到目前为止,您尝试了什么?给我们看一些递归