Skip to content

百度:模版渲染 #36

Open
Open

Description

@sisterAn

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

示例:

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

要求:

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

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

Activity

  1. changed the title [-]前端进阶算法5:一看就懂的队列及配套算法题[/-] [+]待录入[/+] on May 7, 2020
  2. changed the title [-]待录入[/-] [+]百度:模版渲染[/+] on May 8, 2020
  3. 7777sea commented on May 9, 2020

    @7777sea
    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('');
        }
  4. 2384830985 commented on May 9, 2020

    @2384830985
    let render = (template, context)=>{
            let tem = template
            let reg = /\{\{(\w{1,})\}\}/g;
            return tem.replace(reg,function(v,x,y){
                return context[x.trim()]
            })
        }
  5. onlyil commented on May 9, 2020

    @onlyil
    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岁,他少年出外谋生,独力支持,做了许多大事。
  6. luweiCN commented on May 9, 2020

    @luweiCN
    function render(template, context) {
    	return template.replace(/{{(.*?)}}/g, function (match, key, index) {
    		return context[key.trim()] || ''
    	})
    }
  7. sisterAn commented on May 10, 2020

    @sisterAn
    OwnerAuthor

    解答:使用正则 + 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岁"

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

  8. WJmascara commented on May 12, 2020

    @WJmascara

    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);
    });
    }

  9. zjhlaap commented on Jul 10, 2020

    @zjhlaap
    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));
  10. mugongxu commented on Aug 6, 2020

    @mugongxu
    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>
  11. caitlinChang commented on Sep 5, 2020

    @caitlinChang
    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)
    
  12. xllpiupiu commented on Oct 2, 2021

    @xllpiupiu
    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))
  13. AirKK commented on Apr 7, 2022

    @AirKK
    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岁,就可以帮父亲做事,减轻家里负担
  14. kangkang123269 commented on Feb 23, 2023

    @kangkang123269

    续楼上另一直处理方法

    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions