Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

百度:模版渲染 #36

Open
sisterAn opened this issue May 7, 2020 · 12 comments
Open

百度:模版渲染 #36

sisterAn opened this issue May 7, 2020 · 12 comments
Labels

Comments

@sisterAn
Copy link
Owner

sisterAn commented May 7, 2020

实现一个 render(template, context) 方法,将 template 中的占位符用 context 填充。

示例:

var template = "{{name}}很厉害,才{{age}}岁"
var context = {name:"bottle",age:"15"}
输入:template context
输出:bottle很厉害,才15岁

要求:

  • 级联的变量也可以展开
  • 分隔符与变量之间允许有空白字符

相关文章可查看:一行代码实现一个简单的模板字符串替换

@sisterAn sisterAn changed the title 前端进阶算法5:一看就懂的队列及配套算法题 待录入 May 7, 2020
@sisterAn sisterAn added the 百度 label May 8, 2020
@sisterAn sisterAn changed the title 待录入 百度:模版渲染 May 8, 2020
@7777sea
Copy link

7777sea commented May 9, 2020

const answer = (contentTpl, contentTplData, noMatchStr = "-") => {
        let reg = "(.*)";
        const keys = [];
        let current = [];
        Object.keys(contentTplData).forEach((key) => {
            const index = contentTpl.indexOf(key);
            if(index >= 0) {
                current.push({
                    index,
                    value: key
                })
            }
        });
    
        const sortBy = (field) => (a,b) => (a[field] - b[field]);
    
        current.sort(sortBy('index')).forEach(item => {
            reg += `\\\{{${item.value}}}(.*)`;
            keys.push(item.value);
        });
    
        const contents = [];
        const matchArr = contentTpl.match(new RegExp(reg));
    
        (matchArr ? matchArr.slice(1) : []).forEach((item, index) => {
            item = item.replace(/\{{(.*)}}/, noMatchStr);
    
            contents.push(item);

            const key = keys[index]

            if(key !== undefined){
                contents.push(contentTplData[key]);
            }
        });
        return contents.join('');
    }

@2384830985
Copy link

2384830985 commented May 9, 2020

let render = (template, context)=>{
        let tem = template
        let reg = /\{\{(\w{1,})\}\}/g;
        return tem.replace(reg,function(v,x,y){
            return context[x.trim()]
        })
    }

@onlyil
Copy link

onlyil commented May 9, 2020

const render = (template, context) => {
    const getVal = (obj, props) => {
        if (props.length === 0) {
            return obj
        }
        return getVal(obj[props.shift()], props)
    }

    return template.replace(/\{\{\s*(\w+(\.\w+)*)\s*\}\}/g, (p1, p2) => {
        return getVal(context, p2.split('.'))
    })
}

const template = '{{name}}很厉害,才{{age}}岁,他少年{{obj.a}},独力支持,做了{{obj.b.c}}。'
const context = {
    name: '二月',
    age: '15',
    obj: {
        a: '出外谋生',
        b: {
            c: '许多大事'
        }
    }
}

console.log(render(template, context))
// 二月很厉害,才15岁,他少年出外谋生,独力支持,做了许多大事。

@luweiCN
Copy link

luweiCN commented May 9, 2020

function render(template, context) {
	return template.replace(/{{(.*?)}}/g, function (match, key, index) {
		return context[key.trim()] || ''
	})
}

@sisterAn
Copy link
Owner Author

sisterAn commented May 10, 2020

解答:使用正则 + trim

  • 利用非贪婪匹配 /\{\{(.*?)\}\}/g 匹配到到所有的 {{name}}{{age}}
  • 利用 str.replace(regexp|substr, newSubStr|function) ,其中第二个参数可以是 fucntion (replacement) ,该函数的返回值将替换掉第一个参数匹配到的结果,将所有匹配到的字符替换成指定的字符
  • 最后,String.prototype.trim() 去除分隔符与变量之间空白字符
var template = "{{name}}很厉害,才{{age}}岁"
var context = {name:"bottle",age:"15"}
function render(template, context) {
  return template.replace(/{{(.*?)}}/g, (match, key) => context[key.trim()])
}
render(template, context)
// "bottle很厉害,才15岁"

详细解答可查看:一行代码实现一个简单的模板字符串替换

@WJmascara
Copy link

function render(template, context) {
const rule = /{{(.*?)}}/g;
return template.replace(rule, function($, key) {
const arr = key.trim().split('.');
return arr.reduce((cal, item) => {
return cal[item];
}, context);
});
}

@zjhlaap
Copy link

zjhlaap commented Jul 10, 2020

var str = "{{name}}很厉害,才{{age}}岁,他才华横溢,这是第{{queue.ll.cc}}首歌了。";
var obj = {name: '周杰伦', age: 15, queue: { queue1: '1001', ll: { cc: '337' } }};
str.replace(/\{\{(.*?)\}\}/g, ($0, $1) => !$1.includes('.') ? obj[$1] : $1.split('.').reduce((acc, current) => acc[current], obj));

@mugongxu
Copy link

mugongxu commented Aug 6, 2020

let template = '<div><p>{{ name }}</p><p>{{ age }}</p><p>{{ info.member }}</p><p>{{ list.join("+") }}</p></div>';

function render(template, context) {
    return template.replace(/\{\{\s*(.*?)\s*\}\}/g, function(match, $1) {
        let str = '';
        with(context) {
            str = $1 ? eval($1) : '';
        }
        return str; 
    });
}
render(template, {
    name: '李雷',
    age: 10,
    info: {
        member: 5,
        active: 10
    },
    list: [1,2,3,4]
});
// <div><p>李雷</p><p>10</p><p>5</p><p>1+2+3+4</p></div>

@caitlinChang
Copy link

function render(template,context){
    let reg = /\{\{\s*\w+(\.\w+)*\s*\}\}/g
    return template.replace(reg,function(match){
      return match.replace(/{|}/g,'').trim().split('.').reduce((prev,cur) => prev[cur],context)
    })
}
let context = {
  name:'lily',
  age:18,
  family:{
    count:3
  }
}
let template = '{{ name }}很name厉害,才{{age}}岁,家里有{{family.count}}口人'

let result = render(template,context)
console.log(result)

@xllpiupiu
Copy link

const render = (template,context) => {
    let defaultTagRe = /\{\{((?:.|\r?\n)+?)\}\}/g
    return template.replace(defaultTagRe,(match,key,index,str)=>{
        return context[key.trim()]
    })
}
console.log(render(template,context))

@AirKK
Copy link

AirKK commented Apr 7, 2022

function render(template, context) {
    return template.replace(/\{\{(.*?)\}\}/g,(match,key)=>{
        let arr =key.split('.')
        return arr.reduce((pre,cur)=>{
            return pre[cur.trim()]
        },context)
    })
}

const template = "{{name}}很厉害,才{{age }}岁,就可以帮{{person.father}}做事,{{deep.a.b}}";

const context = { name: "marcKun", age: "22" ,person:{father:'父亲'},deep:{a:{b:'减轻家里负担'}} }

console.log(render(template, context));//marcKun很厉害,才22岁,就可以帮父亲做事,减轻家里负担

@kangkang123269
Copy link

续楼上另一直处理方法

function render(template, context) {
  // 使用正则表达式匹配模板字符串中的变量名,并用上下文对象中的对应值替换
  var result = template.replace(/{{(.*?)}}/g, function(match, key) {
    // 使用 eval 函数将变量名转换为上下文对象中对应的值
    try {
      return eval('context.' + key.trim());
    } catch (e) {
      return '';
    }
  });

  return result;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests