BB-Code-RegEx в JavaScript

У меня есть этот кусок кода:

var s_1 = 'blabla [size=42]the answer[/size] bla bla blupblub';
var s_2 = 'blabla [size=42]the answer[/size] bla bla blupblub [size=32] 32 [/size]';

alert('Test-String:\n' + s_1 + '\n\nReplaced:\n' + size(s_1));
alert('Test-String:\n' + s_2 + '\n\nReplaced:\n' + size(s_2));


function size(s) {
    var reg = /\[size=(\d{1,2})\]([\u0000-\uFFFF]+)\[\/size\]/gi;
    s = s.replace(reg, function(match, p1, p2) {
        return '<span style="font-size: ' + ((parseInt(p1) > 48) ? '48' : p1) + 'px;">' + p2 + '</span>';
    })
    return s;    
}

Предполагается заменить все вхождения тегов "[size = nn] [/ size]", но он заменяет только внешние. Я не могу понять, как заменить их всех. (Пожалуйста, не рекомендуйте использовать PHP-скрипт, я бы хотел получить предварительный просмотр текста в формате BB-кода)

Проверь это

 ridgerunner17 окт. 2012 г., 17:03
Если ваши теги вложены, вы сможете сопоставить только самые внутренние теги, но вы можете сделать это итеративно изнутри. (С помощью PHP (который имеет рекурсивные выражения) вы также можете делать это извне.)мой недавний ответ на аналогичный вопрос для деталей как. Обратите внимание, что ни один из ответов ниже правильно не обрабатывает вложенные теги.

Ответы на вопрос(4)

var reg = /\[size=(\d{1,2})\]([\u0000-\uFFFF]+?)\[\/size\]/gi;
                                              ↑
                                    make it lazy (non-greedy)

который так же, как

var reg = /\[size=(\d{1,2})\](.+?)\[\/size\]/gi;
 Ωmega17 окт. 2012 г., 16:42
@Gabber - Использованиеcharmap применение :)
 Gabber17 окт. 2012 г., 16:38
Арр, где ты взял эту верхнюю стрелу? Я боролся целую вечность, используя^ ... Просто шучу, но никогда не думал об использовании ↑ :)
Решение Вопроса
Соответствующие (возможно вложенные) теги BBCode

если элементы вложены. Это может быть достигнуто одним из двух способов; сопоставление изнутри (рекурсивное выражение не требуется) или извне (что требует рекурсивного выражения). (Смотрите также мой ответ на аналогичный вопрос:PHP, вложенные шаблоны в preg_replace) Однако, поскольку движок регулярных выражений Javascript не поддерживает рекурсивные выражения, единственный способ (правильно) сделать это с помощью регулярных выражений - это изнутри. Ниже приведена проверенная функция, которая заменяет теги BBCode SIZE на теги SPAN html изнутри. Обратите внимание, что (быстрое) регулярное выражение ниже является сложным (во-первых, он реализует Джеффри Фридла"Разворачивание-The-петля" Техника эффективности - см .:Освоение регулярных выражений (3-е издание) подробности), и IMO все сложные регулярные выражения должны быть тщательно прокомментированы и отформатированы для удобства чтения. Поскольку Javascript не имеет режима свободного пробела, приведенное ниже регулярное выражение сначала представляется полностью прокомментированным в режиме свободного пробела PHP. Фактически используемое регулярное выражение без комментариев js совпадает с подробным комментарием.

Regex для соответствия внутренним (возможно, вложенным) тегам SIZE:
// Regular expression in commented (PHP string) format.
$re = '% # Match innermost [size=ddd]...[/size] structure.
    \[size=            # Literal start tag name, =.
    (\d+)\]            # $1: Size number, ending-"]".
    (                  # $2: Element contents.
      # Use Friedls "Unrolling-the-Loop" technique:
      #   Begin: {normal* (special normal*)*} construct.
      [^[]*            # {normal*} Zero or more non-"[".
      (?:              # Begin {(special normal*)*}.
        \[             # {special} Tag open literal char,
        (?!            # but only if NOT start of
          size=\d+\]   # [size=ddd] open tag
        | \/size\]     # or [/size] close tag.
        )              # End negative lookahead.
        [^[]*          # More {normal*}.
      )*               # Finish {(special normal*)*}.
    )                  # $2: Element contents.
    \[\/size\]         # Literal end tag.
    %ix';
Функция Javascript:parseSizeBBCode(text)
function parseSizeBBCode(text) {
    // Here is the same regular expression in javascript syntax:
    var re = /\[size=(\d+)\]([^[]*(?:\[(?!size=\d+\]|\/size\])[^[]*)*)\[\/size\]/ig;
    while(text.search(re) !== -1) {
        text = text.replace(re, '<span style="font-size: $1pt">$2</span>');
    }
    return text;
}
Пример ввода:
r'''
[size=10] size 10 stuff
    [size=20] size 20 stuff
        [size=30] size 30 stuff [/size]
    [/size]
[/size]
'''
Пример вывода:
r'''
<span style="font-size: 10pt"> size 10 stuff
    <span style="font-size: 20pt"> size 20 stuff
        <span style="font-size: 30pt"> size 30 stuff </span>
    </span>
</span>
'''
Отказ от ответственности - не используйте это решение!

Обратите внимание, что использование регулярных выражений для разбора BBCode чревато опасностью! (Здесь много не упомянутых здесь «ошибок»). Многие скажут, что этоневозможно, Однако я был бы категорически не согласен и фактически написал полный синтаксический анализатор BBCode (в PHP), который использует рекурсивные регулярные выражения и работает довольно хорошо (ибыстрый). Вы можете увидеть это в действии здесь:Новый парсер FluxBB 2011 года (Обратите внимание, что он использует некоторыеочень сложные регулярные выражения Не для слабонервных).

Но в целом, я бы настоятельно рекомендовал не анализировать BBCode с помощью регулярных выражений, если у вас нет очень глубокого и глубокого понимания регулярных выражений (что можно получить из тщательного изучения и практикиШедевр фридла). Другими словами, если вы не мастер регулярных выражений (т.е. регулярное выражениегуру), избегайте их использования для любых, кроме самых тривиальных приложений.

 John Doe17 окт. 2012 г., 17:17
спасибо @all, это именно то, что я искал :)

([\u0000-\uFFFF]+?) (Непроверенные), это говорит о том, чтобы остановить при первом появлении[/size] вместо того, чтобы идти прямо к последнему

РЕДАКТИРОВАТЬ:

Да, проверено,кажется нормально

Ваш ответ на вопрос