Проблема разбора регулярного выражения BBCode - PullRequest
0 голосов
/ 19 декабря 2010

Итак, у меня есть Javascript, который преобразует BBCode в HTML, который, кажется, работает хорошо, но у меня есть проблема.

Вот одно из выражений, которое работает , которое я использую дляпреобразуйте BB-теги [b] и [/ b] в и .

str = str.replace(/\[b\]((\s|\S)*?)\[\/b\]/ig, '<b>$1</b>');

Это также преобразует последовательные теги.Например,

[b] str1 [/ b] [b] str2 [/ b]

становится

str1 str2

Что хорошо;это то, что я хочу сделать.Однако, когда я пытаюсь сопоставить теги кавычек, например,

str = str.replace(/\[quote\]((\s|\S)*?)\[\/quote\]/ig, '<span class="quotebox">$1</span>');

, где str -

[quote] Уровень 1 гнезда [quote] Уровень 2 гнезда [/ quote] [/цитата]

только первый тег сопоставляется и преобразуется, поэтому я получу вывод, похожий на

Гнездо уровня 1 [цитата] Гнездо уровня 2

[/ quote]

С последним тегом цитаты вне поля кавычек - он должен быть вложен в другой.Справка?

Также, если это уместно, класс quotebox выглядит следующим образом:

.quotebox {рамка: вставка 1px, черная;Дисплей: блок;край дно: 5px;Запас-топ: 5px;обивка: 2px 2px 2px 4px;}

1 Ответ

1 голос
/ 19 декабря 2010

Вас только что укусил тот факт, что (реальные) регулярные выражения могут описывать только регулярные языки . Характерная особенность, которую регулярные выражения не могут описать - это рекурсия. Каноническим примером этого является язык Дейка , язык, который состоит из всех строк сбалансированных скобок, таких как (), (())()((())), ((((())))) и т. Д. Это нерегулярно, и По сути, это проблема, которую вы пытаетесь решить: сопоставление соответственно вложенных [b][/b] с, [quote][/quote] с и т. п. Другими словами, с помощью регулярных выражений буквально невозможно делать то, что вы хотите. Тем не менее, вы могли заметить, что я сказал «настоящий». Регулярные выражения, представленные в таких языках, как JavaScript, не являются настоящими регулярными выражениями; у них есть дополнительная сила, в основном (полностью?) проистекающая из обратных ссылок. Например, регулярное выражение (.*)\1 описывает нерегулярный язык. Даже учитывая это, я не думаю, что вы можете соответствовать языку Дейка. 1

Итак, каково решение? Найдите уже существующий конвертер BBCode в HTML, написанный на JavaScript! Это определенно сделает вашу жизнь максимально простой. К сожалению, я не знаю ни одного из них, потому что я не очень много программирую на JavaScript. Этот вопрос StackOverflow указывает на то, что такой вещи может не существовать, и в этом случае вы можете использовать только свой собственный анализатор. Сложнее, конечно, но, безусловно, выполнимо. Наверху моей головы (я не эксперт), вы, вероятно, захотите просмотреть строку, пока не найдете тег. (Распознавание тега может быть хорошей задачей для регулярного выражения.) Если это открывающий тег, поместите его в стек. Если это закрывающий тег, извлеките стек, убедитесь, что закрывающий тег соответствует открывающему тегу, и оберните строку, которую вы видели до сих пор, в соответствующий HTML. Это может не сработать или может быть слишком сложным - это всего лишь мои 2 ¢ после быстрого рассмотрения проблемы.


1: Я не уверен на 100%, но единственный пример регулярного выражения, соответствующего сбалансированным скобкам, который я когда-либо видел, был в Perl, и в него встроен код Perl, чего не может сделать JavaScript , В любом случае, это нецелесообразно - вы пытаетесь использовать инструмент, который значительно усложнит вашу задачу.)

...