Задачі з BB-кодами для самостійного розв'язання

Три практичні задачі для закріплення навичок роботи з BB-кодами та регулярними виразами

1Форматування коментарів

Створіть функцію для форматування коментарів з підтримкою основних тегів:

  • [b]жирний текст[/b]
  • [i]курсив[/i]
  • [u]підкреслений[/u]
  • [code]код[/code]
  • [quote]цитата[/quote]
Вхідні дані:
[b]Цікавий пост![/b] [i]Дуже рекомендую[/i].
Ось приклад коду: [code]function test() { return true; }[/code]
[quote]Це цитата відомого автора[/quote]
Очікуваний результат:
<b>Цікавий пост!</b> <i>Дуже рекомендую</i>.
Ось приклад коду: <code>function test() { return true; }</code>
<blockquote>Це цитата відомого автора</blockquote>
💡 Підказка: Використовуйте регулярні вирази з групами захоплення. Для тега [code] врахуйте, що вміст може містити квадратні дужки.
function formatComment(text) {
    let converted = text;
    
    // [b]...[/b] -> <b>...</b>
    converted = converted.replace(/\[b\](.*?)\[\/b\]/g, '<b>$1</b>');
    
    // [i]...[/i] -> <i>...</i>
    converted = converted.replace(/\[i\](.*?)\[\/i\]/g, '<i>$1</i>');
    
    // [u]...[/u] -> <u>...</u>
    converted = converted.replace(/\[u\](.*?)\[\/u\]/g, '<u>$1</u>');
    
    // [code]...[/code] -> <code>...</code>
    converted = converted.replace(/\[code\](.*?)\[\/code\]/gs, '<code>$1</code>');
    
    // [quote]...[/quote] -> <blockquote>...</blockquote>
    converted = converted.replace(/\[quote\](.*?)\[\/quote\]/gs, '<blockquote>$1</blockquote>');
    
    return converted;
}
Час виконання: O(n) Легко

2Створення посилань та списків

Розробіть парсер для створення посилань та списків:

  • [url=https://example.com]Посилання[/url]
  • [list][*]Елемент 1[*]Елемент 2[/list]
  • [email=user@example.com]Написати[/email]
Вхідні дані:
Корисні ресурси:
[list]
[*][url=https://google.com]Google[/url]
[*][url=https://github.com]GitHub[/url]
[/list]
[email=admin@site.com]Зв'язатися з адміном[/email]
Очікуваний результат:
Корисні ресурси:
<ul>
<li><a href="https://google.com">Google</a></li>
<li><a href="https://github.com">GitHub</a></li>
</ul>
<a href="mailto:admin@site.com">Зв'язатися з адміном</a>
💡 Підказка: Для списків потрібно спочатку знайти теги [list], а потім замінити всі [*] елементи всередині. Використовуйте вкладені цикли або рекурсію.
function parseLinksAndLists(text) {
    let converted = text;
    
    // [url=...]...[/url] -> <a href="...">...</a>
    converted = converted.replace(/\[url=(.*?)\](.*?)\[\/url\]/g, 
        '<a href="$1">$2</a>');
    
    // [email=...]...[/email] -> <a href="mailto:...">...</a>
    converted = converted.replace(/\[email=(.*?)\](.*?)\[\/email\]/g, 
        '<a href="mailto:$1">$2</a>');
    
    // Обробка списків [list]...[/list]
    converted = converted.replace(/\[list\](.*?)\[\/list\]/gs, function(match, content) {
        // Замінюємо [*] на <li> всередині списку
        const listItems = content.replace(/\[\*\](.*?)(?=\[\*\]|$)/gs, 
            '<li>$1</li>');
        return '<ul>' + listItems + '</ul>';
    });
    
    return converted;
}
Час виконання: O(n) Середня

3Розширене форматування тексту

Створіть парсер для складного форматування з підтримкою:

  • [color=red]текст[/color]
  • [size=20]текст[/size]
  • [bg=yellow]текст[/bg]
  • [center]текст[/center]
  • Вкладені теги
Вхідні дані:
[center][b]Заголовок[/b][/center]
[color=blue][size=18]Синій текст розміром 18px[/size][/color]
[bg=yellow]Жовтий фон [b]з жирним текстом[/b][/bg]
Очікуваний результат:
<div style="text-align: center"><b>Заголовок</b></div>
<span style="color: blue; font-size: 18px">Синій текст розміром 18px</span>
<span style="background: yellow">Жовтий фон <b>з жирним текстом</b></span>
💡 Підказка: Для вкладених тегів потрібно обробляти їх у правильному порядку. Можна використати підхід з багаторазовою обробкою або рекурсивну функцію.
function advancedFormatting(text) {
    let converted = text;
    
    // Обробляємо вкладені теги кілька разів
    for (let i = 0; i < 5; i++) { // Максимум 5 рівнів вкладеності
        // [color=...]...[/color]
        converted = converted.replace(/\[color=(.*?)\](.*?)\[\/color\]/gs, 
            '<span style="color: $1">$2</span>');
        
        // [size=...]...[/size]
        converted = converted.replace(/\[size=(.*?)\](.*?)\[\/size\]/gs, 
            '<span style="font-size: $1px">$2</span>');
        
        // [bg=...]...[/bg]
        converted = converted.replace(/\[bg=(.*?)\](.*?)\[\/bg\]/gs, 
            '<span style="background: $1">$2</span>');
        
        // [center]...[/center]
        converted = converted.replace(/\[center\](.*?)\[\/center\]/gs, 
            '<div style="text-align: center">$1</div>');
        
        // Базові теги
        converted = converted.replace(/\[b\](.*?)\[\/b\]/gs, '<b>$1</b>');
        converted = converted.replace(/\[i\](.*?)\[\/i\]/gs, '<i>$1</i>');
        converted = converted.replace(/\[u\](.*?)\[\/u\]/gs, '<u>$1</u>');
    }
    
    return converted;
}
Час виконання: O(k×n) Складно