我正在寻找一种用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>
但是,我有这些Regexes(我将其用于替换()函数):
/{b:([sS]*?)}/gm
/{i:([sS]*?)}/gm
然后结果将成为:
This is <b>bold text and <i>italic</b></i>
标签未正确嵌套。同样,在这种情况下,使用跨度可以解决此问题,但这与" ul"," li"," h1",...如果文本看起来像这样,贪婪的言论也会引起问题:
This is {b:bold text} and {i:italic}
因此,我当前的解决方案是首先使用数据物标签属性来替换所有内容,以指示其实际应该是什么,然后使用jQuery查找所有跨度节点,然后用适当的标签替换它们:
{h:This is a header}
becomes
<span data-tag='h1'>This is a header</span>
becomes
<h1>This is a header</h1>
它运行良好,但是我想知道是否有一种更简单的方法可以做到这一点。中间方法有点像胶带解决方案,我想"美化"它。
有什么建议?
一个简单的堆栈变长
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>"
ditch ditch the Regex并使用其中的许多模板工具之一,例如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。
这是jsfiddle。