只有在正则表达式匹配时才包含正则表达式?

时间:2010-05-21 05:56:58

标签: javascript regex

我有以下内容:

[list]
[*] test
[*] test
[*] test
[/list]

我想创建一个正则表达式,将其转换为:

<ul>
<li>test</li>
<li>test</li>
<li>test</li>
</ul>

我知道正则表达式足以替换简单标签,但在这种情况下,只有当它们包含在ul中时才需要替换li标签。有没有办法在更换之前检查一下?

如果重要的话,我正在使用JavaScript。

2 个答案:

答案 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>";
})