Regex BBCode в HTML - PullRequest
       3

Regex BBCode в HTML

2 голосов
/ 17 июня 2010

Я пишу BBcode конвертер в HTML.
Конвертер должен пропускать незакрытые теги.

Я думал о 2 вариантах сделать это:
1) сопоставить все теги за один раз с помощью одного вызова регулярного выражения, например:

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

, а затем зациклите MatchCollection, используя 2 указателя, чтобы найти начальные и открытые теги, а затем замените правый 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]

Ответы [ 2 ]

2 голосов
/ 17 июня 2010

Один из вариантов - использовать больше SAX-подобный синтаксический анализ, при котором вместо поиска конкретного регулярного выражения, которое вы ищете [, нужно, чтобы ваша программа обработала, что даже каким-то образом, ищите ], обработайте этодаже и т. д. Хотя это более многословно, чем регулярное выражение, его легче понять и оно не обязательно будет медленнее.

1 голос
/ 17 июня 2010
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>");
...