#ifdef _MSC_VER
    #define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
#endif

#include <cstddef>
#include <cstdlib>
#include <iostream>
#include <string>
#include <algorithm>
#include <regex>
#include <codecvt>

#ifdef _WIN32
    #if !defined(NOMINMAX)
        #define NOMINMAX
    #endif
    #if !defined(WIN32_LEAN_AND_MEAN)
        #define WIN32_LEAN_AND_MEAN
    #endif
    #include <Windows.h>
#endif

auto main() -> int
{
    #ifdef _WIN32
        SetConsoleOutputCP(CP_UTF8);
    #endif

    std::string json_string  = "Json mit dem UE [u]00fc, dem AE [u]00e4 und der Kuh [u]1f42e ;-)";

    std::regex unicode_regex("\\[u\\]([0-9abcdefABCDEF]{2,8})");
    std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert;

    std::string utf8_string;
    std::size_t i = 0;

    std::for_each(
        std::sregex_iterator{
            std::cbegin(json_string),
            std::cend(json_string),
            unicode_regex
        },
        std::sregex_iterator{},
        [&](std::smatch match){
            // JSON-String von letzter Position bis zum Match anhängen.
            utf8_string.append(json_string.substr(i, match.position() - i));
            // Submatch via strtoul in char32_t umwandeln, nach UTF-8
            // konvertieren und anhängen.
            utf8_string.append(
                convert.to_bytes(
                    std::strtoul(match.str(1).c_str(), nullptr, 16)
                )
            );
            i = match.position() + match.length();
        }
    );
    // Rest des JSON-String anhängen.
    utf8_string.append(json_string.substr(i));

    std::cout << json_string << std::endl;
    std::cout << utf8_string << std::endl;
}