我正在寻找一种方法来正确地用他们的HTML等价替换嵌套的自定义标签。例如,假设我们有以下文本:
This is {b:bold text}
应该成为:
This is <b>bold text</b>
我知道我可以 - 并且可能应该 - 使用像“大胆”类的跨度而不是旧的“b”标签,但是有一个原因我坚持使用“b”来达到目的这个例子。我可能有嵌套标签:
This is {b:bold text and {i:italic}}
应该成为:
This is <b>bold text and <i>italic</i></b>
但是,我有这些正则表达式(我使用replace()函数):
/\{b:([\s\S]*?)\}/gm
/\{i:([\s\S]*?)\}/gm
然后结果将成为:
This is <b>bold text and <i>italic</b></i>
标签没有正确嵌套。同样,在这种情况下,使用跨度可以解决这个问题,但这不适用于“ul”,“li”,“h1”等... 如果文本如下所示,贪婪的正则表达式也会引起问题:
This is {b:bold text} and {i:italic}
所以我当前的解决方案是首先用span替换所有内容,使用data-tag属性指示它实际应该是什么,然后使用jQuery查找所有span节点并用适当的标记替换它们:
{h:This is a header}
becomes
<span data-tag='h1'>This is a header</span>
becomes
<h1>This is a header</h1>
它运作良好,但我想知道是否有更简单的方法来做到这一点。中间方法感觉有点像胶带解决方案,我想“美化”它。
有什么建议吗?
答案 0 :(得分:1)
简单的堆栈有很长的路要走
function doReplace( str ) {
var stack = [],
ret = [],
ch;
for( var i = 0, l = str.length; i < l; ++i ) {
var ch = str.charAt(i);
if( ch === "{" ) {
var pos = str.indexOf( ":", i+1);
if( pos < 0 ) {
throw new SyntaxError();
}
var tagName = str.substring( i + 1, pos);
if( /[^A-Za-z0-9]/.test(tagName)) {
throw new SyntaxError();
}
ret.push( "<" + tagName + ">" );
stack.push( tagName);
i+= tagName.length + 1;
}
else if( ch === "}" ) {
if( !stack.length ) {
throw new SyntaxError();
}
var tagName = stack.pop();
ret.push( "</" + tagName + ">" );
}
else {
ret.push( ch );
}
}
if( stack.length ) {
throw new SyntaxError();
}
return ret.join("");
}
doReplace( "This is {b:bold text {i:italic text{i:italic text{i:italic text{i:italic text{i:italic text{i:italic text}}}}}}}")
//"This is <b>bold text <i>italic text<i>italic text<i>italic text<i>italic text<i>italic text<i>italic text</i></i></i></i></i></i></b>"
答案 1 :(得分:0)
抛弃正则表达式并使用其中一种模板工具,例如Mustache或t.js。
编辑: 已修复!
...但如果你在生活中避免这种简单,那么就是如何用正则表达式来做到这一点:
var rex = /\{(b|i):([^{}]*)\}/igm,
parse = function(txt) {
var cnt = 0,
more = true;
while (more) {
txt = txt.replace(rex, function(match, $1, $2) {
return "<" + $1 + ">" + $2 + "</" + $1 + ">";
});
more = rex.test(txt);
cnt++;
}
return txt;
};
所以你打电话给parse
并传递你的字符串。它递归地解析您的字符串,直到找不到其他标记。这个新的工作相反,解析不的项目,然后向外移动。
要实现您添加的H1示例,您可以改为使用{h1:This is the header}
并将其添加到(b|i)
子句中,或者在替换函数中使用switch
语句而不是仅使用{{1}}语句返回1美元。
这是JSFiddle。