我有以下内容:
[list]
[*] test
[*] test
[*] test
[/list]
我想创建一个正则表达式,将其转换为:
<ul>
<li>test</li>
<li>test</li>
<li>test</li>
</ul>
我知道正则表达式足以替换简单标签,但在这种情况下,只有当它们包含在ul中时才需要替换li标签。有没有办法在更换之前检查一下?
如果重要的话,我正在使用JavaScript。
答案 0 :(得分:3)
鉴于文字:
[*] test1
[list]
[*] test2
[*] test3
[*] test4
[/list]
[*] test5
正则表达式:
\[\*]\s*([^\r\n]+)(?=((?!\[list])[\s\S])*\[/list])
仅匹配[*] test2
,[*] test3
和[*] test4
。但是如果可以嵌套[list]
,或者需要解析更广泛的BB类语言,我选择合适的解析器。
要进行替换,请将我建议的正则表达式替换为:
<li>$1</li>
然后将[list]
替换为<ul>
,将[/list]
替换为</ul>
(假设[list]
和[/list]
仅用于列表而不是出现在评论或字符串文字或其他东西)。
running the following snippet时:
var text = "[*] test1\n"+
"\n"+
"[list]\n"+
"[*] test2\n"+
"[*] test3\n"+
"[*] test4\n"+
"[/list]\n"+
"\n"+
"[*] test5\n"+
"\n"+
"[list]\n"+
"[*] test6\n"+
"[*] test7\n"+
"[/list]\n"+
"\n"+
"[*] test8";
print(text + "\n============================");
text = text.replace(/\[\*]\s*([^\r\n]+)(?=((?!\[list])[\s\S])*\[\/list])/g, "<li>$1</li>");
text = text.replace(/\[list]/g, "<ul>");
text = text.replace(/\[\/list]/g, "</ul>");
print(text);
打印以下内容:
[*] test1
[list]
[*] test2
[*] test3
[*] test4
[/list]
[*] test5
[list]
[*] test6
[*] test7
[/list]
[*] test8
============================
[*] test1
<ul>
<li>test2</li>
<li>test3</li>
<li>test4</li>
</ul>
[*] test5
<ul>
<li>test6</li>
<li>test7</li>
</ul>
[*] test8
可能会有一个小的解释:
\[\*]\s*
匹配子字符串[*]
,后跟零个或多个空格字符; ([^\r\n]+)
吞噬该行的其余部分并将其保存在匹配组1中; (?=((?!\[list])[\s\S])*\[/list])
确保每个匹配组1必须在之前有一个子字符串[/list]
,而不包围[list]
修改强>
或者更好的是,按照Gumbo对此答案的评论建议:匹配所有[list] ... [/list]
,然后替换其中的所有[*] ...
。
答案 1 :(得分:2)
这是Bart K.建议的更好方法:
[list] … [/list]
[*]
这将确保只替换[*]
中的[list] … [/list]
。
代码:
str.replace(/\[list]([\s\S]*?)\[\/list]/g, function($0, $1) {
return "<ul>" + $1.replace(/^ *\[\*] *(.*)/gm, "<li>$1</li>") + "</ul>";
})