Обработка подматричек Javascript RegEx

8

javascript,regex,markdown,

JavaScript, регулярное выражение, уценки,

Ответов: 1


3

Самое простое решение - заменить все теги, независимо от того, закрыты они или нет, и разрешить .innerHTMLработу, если они совпадают, или нет, это будет намного более устойчивым таким образом.

var tagreg = /[(/?)(b|u|i|s|center|code)]/ig
div.innerHTML="[b][i]helloworld[/b]".replace(tagreg, "<$1$2>") //no closing i
//div.inerHTML=="<b><i>helloworld</i></b>"

1

AFAIK вы не можете выразить рекурсию с помощью регулярных выражений.

Однако вы можете сделать это с помощью .NET System.Text.RegularExpressions, используя сбалансированное сопоставление. См. Больше здесь: http://blogs.msdn.com/bclteam/archive/2005/03/15/396452.aspx

Если вы используете .NET, вы, вероятно, сможете реализовать то, что вам нужно, с обратным вызовом. Если нет, вам, возможно, придется катить собственный небольшой парсер.

Опять же, если вы можете позволить себе попасть на сервер, вы можете использовать полный парсер. :)

Для чего вам это нужно? Если это для чего-то другого, кроме предварительного просмотра, я настоятельно рекомендую делать обработку на стороне сервера.


0

Вы можете просто повторно применить регулярное выражение, пока оно больше не будет соответствовать. Это будет делать нечетные вещи, такие как «[b] [b] foo [/ b] [/ b]" => "<b> [b] foo </ b> [/ b]" => "<b> <b > foo </ b> </ b> ", но, насколько я вижу, конечный результат по-прежнему будет разумной строкой с соответствующими (хотя и не обязательно правильно вложенными) тегами.

Или, если вы хотите сделать это «правильно», просто напишите простой рекурсивный парсер спуска. Хотя люди могут ожидать, что «[b] foo [u] bar [/ b] baz [/ u]» будет работать, что сложно распознать с помощью синтаксического анализатора.


0

Причина, по которой вложенный блок не заменяется, заключается в том, что совпадение для [b] помещает позицию после [/ b]. Таким образом, все, что соответствует ((.) {1,}?), Игнорируется.

Можно написать рекурсивный синтаксический анализатор на стороне сервера - Perl использует qr //, и Ruby, вероятно, имеет что-то подобное.

Хотя вам не обязательно нужна настоящая рекурсивность. Вы можете использовать относительно простой цикл для равномерной обработки строки:

var s = '[b]hello[/b] [u]world[/u] [b]foo [u]to the[/u] bar[/b]';
var exptags = /[(b|u|i|s|center|code){1}]((.){1,}?)[/(1){1}]/ig;

while (s.match(exptags)) {
   s = s.replace(exptags, "<$1>$2</$1>");
}

document.writeln('<div>' + s + '</div>'); // after

В этом случае он выполнит 2 прохода:

0: [b]hello[/b] [u]world[/u] [b]foo [u]to the[/u] bar[/b]
1: <b>hello</b> <u>world</u> <b>foo [u]to the[/u] bar</b>
2: <b>hello</b> <u>world</u> <b>foo <u>to the</u> bar</b>

Кроме того, несколько советов по очистке RegEx:

var exptags = /[(b|u|i|s|center|code)](.+?)[/(1)]/ig;
  • {1} предполагается, когда нет других спецификаторов счетчика
  • {1,} можно сократить до +

0

Согласитесь с Ричардом Салаем, но его регулярное выражение не получилось правильно:

var exptags = /[(b|u|i|s|center|code)](.*)[/1]/ig;

чище. Обратите внимание , что я также изменить .+?к .*. Есть две проблемы .+?:

  1. вы не будете сопоставлять [u] [/ u], так как между ними нет хотя бы одного символа (+)
  2. не-жадный матч не будет иметь ничего общего с тем же самым тегом, вложенным внутри себя (?)
JavaScript, регулярное выражение, уценки,
Похожие вопросы
Яндекс.Метрика