2011-08-09 216 views
1

写了一些代码,以帮助Find special markers in sequence and do something to the text in between正则表达式工作不正常

这里是小提琴:http://jsfiddle.net/mplungjan/GyPHH/

为什么它只是每个正则表达式运行一次,你会如何处理嵌套项

<div id="texts"> 
**this** **would** make it **bold** __this would__ make it __underlined__ 

__**how about bold and underlined**__ 

and 

**__the other way around__** 
</div> 
var res = { 
    boldIt:/\*\*(.*?)\*\*/g, 
    underlineIt:/\_\_(.*?)\_\_/g 
} 
$.each(res, function(type, re) { 
    var s = $("#texts").html();  
    var m = re.exec(s); 
    var found = m[0]; 
    $.each(m, function(index, value) {  
    if (index==0) return true; 
    var html = s.replace(found,'<span class="'+type+'" >'+value+'</span>',"g"); 
    $("#texts").html(html); 
    }); 
}); 
+2

像这样的嵌套问题是* irregular *上下文无关语法的教科书示例。正则表达式不会可靠地解析它们,您需要一个FSM。不,不是[那个](http://en.wikipedia.org/wiki/Flying_Spaghetti_Monster),[那个](http://en.wikipedia.org/wiki/Finite_state_machine)。 – Malvolio

+0

感谢@Malvolio – mplungjan

回答

2

这是因为你正在替换一遍又一遍地找到的第一个值。如果你检查结果,你会发现你已经用多个标签包装了第一个匹配。

您正在做一个双循环,您首先找到匹配项,然后替换每个匹配项。你可以直接替换它们。此外,您可以将HTML取出并放回每次迭代,但只需执行一次:

var res = { 
    boldIt:/\*\*(.*?)\*\*/g, 
    underlineIt:/\_\_(.*?)\_\_/g 
} 
var s = $("#texts").html();  
$.each(res, function(type, re) { 
    s = s.replace(re,'<span class="'+type+'" >$1</span>'); 
}); 
$("#texts").html(s); 
+0

@mplungjan:我只是使用了错误的变量来放回html。 http://jsfiddle.net/Guffa/AkCED/2/ – Guffa

+0

我知道。固定。现在原来的问题变得更加棘手 - 我的新小提琴又一次失败了:(http://jsfiddle.net/mplungjan/bhTAM/ – mplungjan

+0

@mplungjan:您试图使用'$('#texts')' class =“texts”'。将其更改为一个id或更改选择器。 – Guffa

3

该代码是不必要的复杂。试试这个:

var res = { 
    boldIt:/\*\*(.*?)\*\*/g, 
    underlineIt:/\_\_(.*?)\_\_/g 
} 

$.each(res, function(type, re) { 
    var txt = $("#texts").html(); 
    $("#texts").html(txt.replace(re, '<span class="'+type+'" >$1</span>')); 
}); 
+0

每次都会替换东西。,Guffa的不是 – mplungjan

+0

我不知道你的意思,但我同意Guffa的解决方案更优雅。 – JJJ