2

我将 BBcode 转换器编写为 html。
转换器应该跳过未关闭的标签。

我考虑了 2 个选项来做到这一点:
1)使用一个正则表达式调用一次匹配所有标签,例如:

Regex re2 = new Regex(@"\[(\ /?(?:b|i|u|quote|strike))\]");
MatchCollection mc = re2.Matches(sourcestring);

然后,使用 2 个指针循环 MatchCollection 以查找开始和打开标记,而不是用正确的 html 标记替换。

2)为每个标签多次调用正则表达式并直接替换:

Regex re = new Regex(@"\[b\](.*?)\[\/b\]"); 
string s1 = re.Replace(sourcestring2,"<b>$1</b>");

什么更有效率?

第一个选项使用一个正则表达式,但需要我遍历所有标签并找到所有对,并跳过没有对的标签。
另一个积极的方面是我不关心标签之间的内容,我只是工作并使用位置替换它们。

在第二个选项中,我不需要担心循环和制作特殊的替换功能。
但需要执行多个正则表达式和替换。

你有什么建议?

如果第二个选项是正确的,则正则表达式有问题 \[b\](.*?)\[\/b\]

我该如何修复它以匹配多行,例如:

[b]
        test 1
[/b]

[b]
        test 2
[/b]
4

2 回答 2

2

一种选择是使用更多类似 SAX 的解析,而不是查找您要查找的特定正则表达式[,然后让您的程序以某种方式处理它,查找],甚至处理它等等。虽然比正则表达式可能更容易理解,并且不一定会更慢。

于 2010-06-17T18:57:33.213 回答
1
r = new System.Text.RegularExpressions.Regex(@"(?:\[b\])(?<name>(?>\[b\](?<DEPTH>)|\[/b\](?<-DEPTH>)|.)+)(?(DEPTH)(?!))(?:\[/b\])", System.Text.RegularExpressions.RegexOptions.Singleline);

 var s = r.Replace("asdfasdf[b]test[/b]asdfsadf", "<b>$1</b>");

那应该只为您提供具有匹配结束标记的元素并且还处理多行(即使我指定了 SingleLine 的选项,它实际上将其视为单行)

它还应该通过忽略第一个 [b] 来正确处理 [b][b][/b]。

至于这种方法是否比你的第一种方法更好,我不能说。但希望这将为您指明正确的方向。

与您的示例一起使用的代码如下: System.Text.RegularExpressions.Regex r;

r = new System.Text.RegularExpressions.Regex(@"(?:\[b\])(?<name>(?>\[b\](?<DEPTH>)|\[/b\](?<-DEPTH>)|.)+)(?(DEPTH)(?!))(?:\[/b\])", System.Text.RegularExpressions.RegexOptions.Singleline);

var s = r.Replace("[b]bla bla[/b]bla bla[b] " + "\r\n" + "bla bla [/b]", "<b>$1</b>");
于 2010-06-17T18:54:22.253 回答