Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Вебмастеру (http://forum.oszone.net/forumdisplay.php?f=22)
-   -   [решено] Правильная регулярка для замены тегов в выводе php (http://forum.oszone.net/showthread.php?t=356146)

Mancoffee 21-02-2025 11:43 3036145

Правильная регулярка для замены тегов в выводе php
 
Есть скрипт (знаю, что не профессиональный), уже замучался с регулярками.
Скрытый текст

Код:

document.addEventListener("DOMContentLoaded", function() {
    document.querySelectorAll("td.e").forEach(function (cell) {
        cell.innerHTML = cell.innerHTML.replace(/_/g, "_<wbr>");
    });
// ---------------------------------
// Замена логотипа
const oldLogo = document.querySelector('img[src*="data:image/png;base64,"]');
if (oldLogo) {
    const newLogo = document.createElement('img');
    newLogo.src = '/res/imgs/phplogo.svg';
    newLogo.alt = 'PHP Logo';
    newLogo.className = 'custom-logo';
    newLogo.style.width = '15vw';
    newLogo.style.height = 'auto';

    const parent = oldLogo.parentElement;

    if (parent.tagName.toLowerCase() === 'a') {
        parent.replaceChild(newLogo, oldLogo);

        // Проверяем, есть ли уже ссылка, если нет — добавляем
        if (!parent.nextElementSibling || !parent.nextElementSibling.classList.contains('logo-text')) {
            const textLink = document.createElement('a');
            textLink.href = 'https://github.com/BlagoYar/beautiful_phpinfo';
            textLink.textContent = 'Designed by BlagoYar';
            textLink.className = 'logo-text';
            textLink.target = '_blank'; // Открывать в новой вкладке
            textLink.rel = 'noopener noreferrer';

            parent.parentElement.insertBefore(textLink, parent.nextSibling);
        }
    }
}



// ---------------------------------
// Замена слова active
function replaceActiveText() {
  const elements = document.querySelectorAll('td.v');

  elements.forEach(element => {
    if (element.textContent.trim() === 'active') {
      const span = document.createElement('span');
      span.classList.add('enabled-text');
      span.textContent = 'active';

      // Заменяем текстовый узел внутри td на span
      element.innerHTML = ''; // Очищаем содержимое td
      element.appendChild(span); // Добавляем span внутрь td
    }
  });
}

// Запускаем функцию после загрузки DOM
if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', replaceActiveText);
} else {
    replaceActiveText(); // DOMContentLoaded уже сработал
}

function replaceFontWithClass() {
    const fontElements = document.querySelectorAll('font[style*="color: #"]');

    fontElements.forEach(element => {
        const style = element.getAttribute('style');
        const colorCode = style.match(/color: (#[\da-fA-F]{3,6})/)[1];
        const colorName = getColorName(colorCode); // Получаем английское название цвета
        const className = `${colorName}-${colorCode.replace('#', '')}`; // Формируем имя класса

        element.classList.add(className);
        element.removeAttribute('style');

        // Создаем CSS правило
        const styleElement = document.createElement('style');
        styleElement.textContent = `.${className} { color: ${colorCode} !important; }`;
        document.head.appendChild(styleElement);
    });
}

function getColorName(hexColor) {
    // Здесь можно добавить более сложную логику для преобразования hex в название цвета.
    // Пока что, для простоты, будем возвращать просто "color"
    return "color"; // В дальнейшем можно улучшить
}

// Запускаем функцию после загрузки DOM
if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', replaceFontWithClass);
} else {
    replaceFontWithClass(); // DOMContentLoaded уже сработал
}

// ---------------------------------
// Замена 0 и 1
const numberMappings = {
    "0": "disabled-int",
    "1": "enabled-int"
};

function replaceNumbersWithSpan(node) {
    const text = node.textContent;
    const regex = new RegExp(`(?:^|\\s)\\b(${Object.keys(numberMappings).join('|')})\\b(?:$|\\s)`, 'g');
    const newContent = text.replace(regex, (match, p1) => {
        const span = document.createElement('span');
        span.className = numberMappings[p1];
        span.textContent = p1;
        return span.outerHTML;
    });

    const parentNode = node.parentNode;
    const tempDiv = document.createElement('div');
    tempDiv.innerHTML = newContent;
    while (tempDiv.firstChild) {
        parentNode.insertBefore(tempDiv.firstChild, node);
    }
    parentNode.removeChild(node);
}

function traverseNodesForNumbers(node) {
    node.childNodes.forEach(child => {
        if (child.nodeType === Node.ELEMENT_NODE) {
            traverseNodesForNumbers(child);
        } else if (child.nodeType === Node.TEXT_NODE) {
            replaceNumbersWithSpan(child);
        }
    });
}

traverseNodesForNumbers(document.body);

// ---------------------------------
// Замена слов
    const wordMappings = {
        "enabled": "enabled-text",
        "Enabled": "enabled-text",
        "disabled": "disabled-text",
        "Disabled": "disabled-text",
        "Off": "disabled-text",
        "On": "enabled-text",
        "no value": "no-text",
        "available": "available-text"
    };

    function replaceWordsWithSpan(node) {
        const text = node.textContent;
        // Улучшенное регулярное выражение:
        const regex = new RegExp(`\\b(?:enabled|Enabled|disabled|Disabled|Off|On|no value|available)\\b`, 'gi');

        const newContent = text.replace(regex, match => {
            const span = document.createElement('span');
            span.className = wordMappings[match];
            span.textContent = match;
            return span.outerHTML;
        });

        const parentNode = node.parentNode;
        const tempDiv = document.createElement('div');
        tempDiv.innerHTML = newContent;
        while (tempDiv.firstChild) {
            parentNode.insertBefore(tempDiv.firstChild, node);
        }
        parentNode.removeChild(node);
    }

    function traverseNodesForWords(node) {
        node.childNodes.forEach(child => {
            if (child.nodeType === Node.ELEMENT_NODE) {
                if (child.tagName !== 'TH') {
                    traverseNodesForWords(child);
                }
            } else if (child.nodeType === Node.TEXT_NODE) {
                replaceWordsWithSpan(child);
            }
        });
    }

    traverseNodesForWords(document.body);

    document.querySelectorAll("td.v").forEach(el => {
        el.childNodes.forEach(node => {
            if (node.nodeType === Node.TEXT_NODE) {
                node.textContent = node.textContent.replace(/\bno\b/g, 'no');
            }
        });
        el.innerHTML = el.innerHTML.replace(/\bno\b(?!-)/g, '<span class="no-text">no</span>');
    });

    const scrollButtonsContainer = document.createElement("div");
    scrollButtonsContainer.classList.add("scroll-buttons");
    document.body.appendChild(scrollButtonsContainer);

    const buttonsData = [
        { symbol: "⬆", action: () => window.scrollTo({ top: 0, behavior: 'smooth' }) },
        { symbol: "⚪", action: () => window.scrollTo({ top: document.body.scrollHeight / 2, behavior: 'smooth' }) },
        { symbol: "⬇", action: () => window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }) }
    ];

    buttonsData.forEach(({ symbol, action }) => {
        const btn = document.createElement("button");
        btn.classList.add("scroll-btn");
        btn.textContent = symbol;
        btn.addEventListener("click", action);
        scrollButtonsContainer.appendChild(btn);
    });

    function updateButtonPosition() {
        const mainContent = document.querySelector(".center");
        if (mainContent) {
            const marginBottom = parseFloat(getComputedStyle(mainContent).marginBottom);
            scrollButtonsContainer.style.bottom = `${marginBottom + 20}px`;
        }
    }

    let scrollTimeout;
    let firstScroll = false;

    function updateButtonsVisibility() {
        if (!firstScroll && window.scrollY > 50) {
            firstScroll = true;
            scrollButtonsContainer.classList.add("visible");
        }

        if (firstScroll) {
            scrollButtonsContainer.classList.add("visible");
            clearTimeout(scrollTimeout);
            scrollTimeout = setTimeout(() => {
                if (!scrollButtonsContainer.matches(":hover")) {
                    scrollButtonsContainer.classList.remove("visible");
                }
            }, 2000);
        }
    }

    window.addEventListener("scroll", () => {
        updateButtonsVisibility();
        updateButtonPosition();
    });

    window.addEventListener("resize", updateButtonPosition);
    scrollButtonsContainer.addEventListener("mouseenter", () => clearTimeout(scrollTimeout));
    scrollButtonsContainer.addEventListener("mouseleave", () => {
        scrollTimeout = setTimeout(() => scrollButtonsContainer.classList.remove("visible"), 2000);
    });

    // Убеждаемся, что кнопки скрыты при загрузке
    scrollButtonsContainer.style.display = "none";

    // Показываем контейнер только после первой прокрутки
    window.addEventListener("scroll", function firstScrollCheck() {
        if (window.scrollY > 50) {
            scrollButtonsContainer.style.display = "flex";
            scrollButtonsContainer.classList.add("visible");
            window.removeEventListener("scroll", firstScrollCheck);
        }
    });

    updateButtonPosition();


});



Всё нужно заменить с учётом, чтобы последующее оформление стилями не затронуло, если эти значения есть где-то в контексте с другими, например "0" встречается в "1.0.25" или "active" в "Previously active authors, editors ..."

Есть несколько ячеек с кодами цветов, нужно каждый под свой цвет/код, пример
<font style="color: [здесь код цвета в формате #FF8000]">#FF8000</font> -> <font class="color-[тот же код цвета в формате #FF8000]">#FF8000</font>

<td class="v">available, disabled </td> -> <td class="v"><span class="v available-text">available</span>,<span class="v disabled-text">disabled </span></td>
<td class="v">active </td> -> <td class="v enabled-text">active </td>
<td class="v">1</td> -> <td class="v enabled-text">1</td>
<td class="v">enabled </td> -> <td class="v enabled-text">enabled </td>
<td class="v">Enabled </td> -> <td class="v enabled-text">Enabled </td>
<td class="v">On</td> -> <td class="v enabled-text">On</td>

<td class="v">0</td> -> <td class="v disabled-text">0</td>
<td class="v">disabled </td> -> <td class="v disabled-text">disabled </td>
<td class="v">Disabled </td> -> <td class="v disabled-text">Disabled </td>
<td class="v">disabled (install ext/bz2) </td> -><td class="v"><span class="disabled-text">disabled </span> (install ext/bz2)</td>
<td class="v">Off</td> -> <td class="v disabled-text">Off</td>

<td class="v">no </td> -> <td class="v no-text">no </td>
<td class="v">no-ctrl</td> -> <td class="v no-text">no-ctrl</td>
<td class="v">nocache</td> -> <td class="v no-text">nocache</td>
<td class="v">no value </td> -> <td class="v no-text">no value </td>

Сейчас работает, но кривовато, где-то enabled в неположенном месте (session_on_enabled), в консоли браузера "[Violation]Forced reflow while executing JavaScript took 46ms"

ПС. Если кому интересно ссылка на проект

Mancoffee 21-02-2025 14:09 3036148

Цитата:

Цитата Mancoffee
Сейчас работает, но кривовато, где-то enabled в неположенном месте (session_on_enabled), в консоли браузера "[Violation]Forced reflow while executing JavaScript took 46ms" »

Всё, решил проблему через php на пути вывода.
Скрытый текст

PHP код:

<?php
    define
('VALID_TOKEN'getenv('VALID_TOKEN_PHPINFO'));

    function 
unauthorizedResponse() {
        
header('HTTP/1.1 401 Unauthorized');
        
readfile("/usr/share/nginx/html/401.html");
        exit;
    }

    if (
$_GET['token'] !== VALID_TOKEN) {
        
unauthorizedResponse();
    }


    
// Функция для вывода User-Agent
    
function getUserAgent() {
        return 
$_SERVER['HTTP_USER_AGENT'];
    }

    
// Функция для определения мобильного устройства
    
function isMobile() {
        
$userAgent $_SERVER['HTTP_USER_AGENT'];

        
// Мобильные устройства: проверка на iPhone, iPad, Android (Mobile), Windows Phone, BlackBerry, IEMobile и Opera Mini
        
if (preg_match('/(iPhone|iPad|iPod|Android.*Mobile|Windows Phone|BlackBerry|IEMobile|Opera Mini)/i'$userAgent)) {
            return 
true;  // Это мобильное устройство
        
}

        
// ПК устройства: если не мобильное, то по умолчанию считаем это ПК
        
return false;
    }

    
// Выбор стилей в зависимости от устройства
    
$cssFile isMobile() ? '/res/css/php_smart.css' '/res/css/php_pc.css';

    
ob_start();
    
phpinfo();  // Выводим phpinfo()
    
$phpinfo ob_get_clean();

?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Custom PHP Info</title>
    <link rel="stylesheet" href="/res/css/php_out.css" type="text/css">
    <link rel="stylesheet" href="<?php echo $cssFile?>" type="text/css">
    <link rel="shortcut icon" href="/res/imgs/php_out_favicon.png" type="image/png">
    <script defer src="/res/js/php_out.js"></script>
</head>
<body>
    <?php

        ob_start
();
        
phpinfo();
        
$phpinfo ob_get_clean();

            
$phpinfo preg_replace('#<style.*?>.*?</style>#is'''$phpinfo);

            
$phpinfo preg_replace_callback(
            
'/<font style="color: (#?[A-Fa-f0-9]{6})">(.*?)<\/font>/',
            function (
$matches) {
                
$color ltrim($matches[1], '#');
                return 
'<span class="color-' $color '">' $matches[2] . '</span>';
            },
            
$phpinfo
        
);

        
$replacements = [
            
'/<td class="v">available, disabled <\/td>/' => '<td class="v"><span class="v available-text">available</span>, <span class="v disabled-text">disabled</span></td>',
            
'/<td class="v">available <\/td>/' => '<td class="v"><span class="v available-text">available</span></td>',
            
'/<td class="v">disabled <\/td>/' => '<td class="v"><span class="v disabled-text">disabled</span></td>',
            
'/<td class="v">active <\/td>/' => '<td class="v"><span class="v enabled-text">active</span></td>',
            
'/<td class="v">1<\/td>/' => '<td class="v"><span class="v enabled-text">1</span></td>',
            
'/<td class="v">enabled <\/td>/' => '<td class="v"><span class="v enabled-text">enabled</span></td>',
            
'/<td class="v">Enabled <\/td>/' => '<td class="v"><span class="v enabled-text">Enabled</span></td>',
            
'/<td class="v">On<\/td>/' => '<td class="v enabled-text">On</td>',
            
'/<td class="v">Off<\/td>/' => '<td class="v disabled-text">Off</td>',
            
'/<td class="v">0<\/td>/' => '<td class="v"><span class="v disabled-text">0</span></td>',
            
'/<td class="v">disabled <\/td>/' => '<td class="v"><span class="v disabled-text">disabled</span></td>',
            
'/<td class="v">Disabled <\/td>/' => '<td class="v"><span class="v disabled-text">Disabled</span></td>',
            
'/<td class="v">disabled \(install ext\/bz2\) <\/td>/' => '<td class="v"><span class="v disabled-text">disabled</span> (install ext/bz2)</td>',
            
'/<td class="v">no <\/td>/' => '<td class="v"><span class="v no-text">no</span></td>',
            
'/<td class="v">no-ctrl<\/td>/' => '<td class="v"><span class="v no-text">no-ctrl</span></td>',
            
'/<td class="v">nocache<\/td>/' => '<td class="v"><span class="v no-text">nocache</span></td>',
            
'/<td class="v">none<\/td>/' => '<td class="v"><span class="v no-text">none</span></td>',
            
'/<td class="v"><i>no value<\/i><\/td>/' => '<td class="v"><i class="no-text">no value</i></td>',
            
'/<tr class="h"><th>(.*?)<\/th><th>enabled<\/th><\/tr>/' => '<tr class="h"><th>$1</th><th class="enabled-text">enabled</th></tr>',
            
'/<td class="v">on<\/td>/' => '<td class="v enabled-text">on</td>',
            
'/<td class="v">off<\/td>/' => '<td class="v disabled-text">off</td>',
            
'/<tr class="h"><th>(.*?)<\/th><th>disabled<\/th><\/tr>/' => '<tr class="h"><th>$1</th><th class="disabled-text">disabled</th></tr>',
            
'/<td class="v">OK <\/td>/' => '<td class="v enabled-text">OK </td>',
            
'/<td class="v">no-cache<\/td>/' => '<td class="v"><span class="v no-text">no-cache</span></td>',
            
'/<td class="v">0 <\/td>/' => '<td class="v"><span class="v disabled-text">0 </span></td>',
            
'/<td class="v"><i>no value<\/i> <\/td>/' => '<td class="v"><i class="no-text">no value</i> </td>',
        ];

    
$phpinfo preg_replace(array_keys($replacements), array_values($replacements), $phpinfo);

    echo 
$phpinfo;
    
?>
</body>
</html>



Всем спасибо за внимание :)


Время: 02:18.

Время: 02:18.
© OSzone.net 2001-