-
-
Notifications
You must be signed in to change notification settings - Fork 241
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
正则表达式模版字符串 #48
Comments
function createTemplate(template = '', option = {}) {
const { dynamic = ['{{', '}}'], statement = '#' } = option
const RE_CONTENT = '[.\\s\\S]*'
const RE_DYNAMIC = new RegExp(
`(${RE_CONTENT}?)${dynamic[0]}(${RE_CONTENT}?)${dynamic[1]}(${RE_CONTENT})`
)
const tokens = []
const createTokens = (tpl) => {
const match = tpl.match(RE_DYNAMIC)
if (match) {
// ['', text, dynamic, nexTemplate] = match
match[1] && tokens.push({
type: 'text',
content: match[1],
})
const dynamicMatch = match[2].trim()
dynamicMatch && tokens.push({
type: dynamicMatch.startsWith(statement) ? 'statement' : 'dynamic',
content: dynamicMatch,
});
match[3] && createTokens(match[3])
} else {
tokens.push({
type: 'text',
content: tpl,
})
}
}
createTokens(template)
return function format(data) {
return tokens.map(({ type, content }) => {
switch (type) {
case 'text':
return content
case 'dynamic':
return data[content]
case 'statement':
const fn = new Function(...Object.keys(data), content.slice(1))
return fn(...Object.values(data))
}
}).join('')
}
}
const template = createTemplate(`
名字: {{ name }}
{{}}
年龄: {{ age }}
{{#
if (age > 18) {
return '成年人'
} else {
return '未成年人'
}
}}
`)
console.log(template({ name: "张三", age: 14 }))
console.log(template({ name: "李四", age: 19 })) |
补一个双指针的写法,效率可能高一点。 const data = {
name: "小明",
age: 16,
school: "第三中学",
classroom: "教室2",
};
// 解构取值
let { name, age, school, classroom } = data;
/**
* @description: 双指针匹配 模板字符串,发现${}
* @param {*} s
* @return {*}
* @author: jlx
*/
function matchStrV2(s) {
let res = "";
for (let i = 0; i < s.length - 1; i++) {
let j = i + 2;
if (s[i] == "$" && s[i + 1] == "{") {
// 直到 右侧括号匹配成功
while (j < s.length && s[j] != "}") j++;
// 说明匹配成功
if (s[j] == "}") {
res += eval(s.substring(i + 2, j));
}
i = j + 1;
} else {
res += s[i];
}
}
return res;
}
let cases =
"${ name } 今年 ${ age } 岁,就读于 ${ school } 今天在 ${ classroom } 上课,${ name } ${ data.age >= 18 ? '成年了' : '未成年' }";
console.log(matchStrV2(cases));
// 小明今年 16岁,就读于 第三中学今天在 教室2上课,小明未成年
// 如果是es6标准的模板字符串``,第二个case好像是非法的 |
面试会考正则吗,完全不会 |
function renderTemplate(template, data) {
const regex = /{{(.*?)}}/g;
return template.replace(regex, (match, key) => {
if (key.startsWith("#")) {
return eval(key.substr(1));
} else {
return data[key.trim()] || "";
}
});
} |
/**
*遇到#表示是表达式
*遇到字符表示变量
*/
String.prototype.render = function (data) {
return this.replace(/{{[\s\S]*?}}/g, match => {
match = match.slice(2, match.length - 2).trim();
// console.log(match)
if (match == "") {
return;
} else if (match[0] == '#') {
return eval(match.slice(1));
} else {
return data[match] || '';
}
})
}
const data = {
name: "小明",
age: 16,
school: "第三中学",
classroom: "教室2"
}
console.log(
"{{ name }} 今年 {{ age }} 岁,就读于 {{ school }} 今天在 {{ classroom }} 上课,{{ name }} {{ #data.age >= 18 ? '成年了' : '未成年' }}".render(data)
);
// 小明 今年 16 岁,就读于 第三中学 今天在 教室2 上课,小明 未成年
console.log(
`{{name}}说了句{{#
if (data.age >= 18) {
"我已经成年了!"
} else {
"我还没有成年!"
}
}}`.render(data)
);
// 小明说了句我还没有成年! |
索性把正则写完整一些,少一些字符串操作吧 function resolveStr(tpl, model) {
const reg = /{{\s*(.+?)\s*}}/g
return tpl.replace(reg, (str, key) => {
if (key.startsWith('#')) {
key = key.slice(1)
return eval(key)
}
console.log(str, key)
return eval(`model.${key}`)
})
} |
String.prototype.render = function (data) {
return this.replace(/{{\s*([\S\s]*?)\s*}}/g, (match, p1) => {
if (p1 && p1[0] === '#') return eval(p1.slice(1))
else return data[p1] || ''
})
} |
'{{1}}222{{3}}'.replace(/({{\w*}})/g,m => {
console.log(m)
}) |
没懂题目啥意思 单纯匹配模板字符串? |
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The text was updated successfully, but these errors were encountered: