You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从RTF格式的std::wstring字符串中提取纯文本内容

从RTF格式std::wstring中提取纯文本的方法

针对你提供的简单RTF内容,有两种可行的提取方案:

方法一:手动解析轻量RTF(适配本例场景)

你的RTF结构简单,仅包含单段文本,可通过过滤RTF控制符直接提取内容:

  • 遍历字符串,跳过{}包裹的格式定义块
  • 跳过所有以\开头的格式命令(如\rtf1、\par)
  • 提取剩余的有效非空白文本

示例代码:

#include <string>
#include <algorithm>
#include <cwctype>

std::wstring extractSimpleRTFText(const std::wstring& rtf) {
    std::wstring result;
    bool inBraceBlock = false;
    bool inControlCommand = false;

    for (wchar_t c : rtf) {
        // 处理大括号包裹的格式块
        if (c == L'{') {
            inBraceBlock = true;
            continue;
        }
        if (c == L'}') {
            inBraceBlock = false;
            continue;
        }
        if (inBraceBlock) continue;

        // 处理\开头的控制命令
        if (c == L'\\') {
            inControlCommand = true;
            continue;
        }
        if (inControlCommand) {
            if (!iswalnum(c)) {
                inControlCommand = false;
                if (!iswspace(c)) result += c;
            }
            continue;
        }

        // 仅保留非空白有效字符
        if (!iswspace(c)) {
            result += c;
        }
    }
    return result;
}

// 使用示例
std::wstring sString = L"{\\rtf1\\ansi\\ansicpg1252\\deff0\\nouicompat\\deflang2057{\\fonttbl{\\f0\\fnil\\fprq12\\fcharset0 Times New Roman;}}\r\n{\\*\\generator Riched20 10.0.19041}\\viewkind4\\uc1 \r\n\\pard\\f0\\fs24 HELLO\\par\r\n}\\r\n";
std::wstring plainText = extractSimpleRTFText(sString);
// plainText 结果为 L"HELLO"

方法二:使用Windows RichEdit控件(通用可靠)

如果需要处理复杂RTF(多段落、特殊格式、嵌入对象等),Windows原生RichEdit控件是最稳妥的方案,步骤如下:

  1. 加载Msftedit.dll库
  2. 创建隐藏的RichEdit窗口
  3. 向控件传入RTF内容
  4. 从控件中提取纯文本

示例代码:

#include <windows.h>
#include <string>
#include <algorithm>
#include <cwctype>

// 链接RichEdit库
#pragma comment(lib, "Msftedit.lib")

std::wstring extractRTFWithRichEdit(const std::wstring& rtf) {
    // 加载RichEdit模块
    LoadLibrary(L"Msftedit.dll");

    // 创建隐藏RichEdit窗口
    HWND hRichEdit = CreateWindowExW(0, MSFTEDIT_CLASS, L"", 
        ES_MULTILINE | ES_READONLY | WS_CHILD,
        0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL);
    if (!hRichEdit) return L"";

    // 设置RTF内容
    SETTEXTEX st = {0};
    st.codepage = CP_UNICODE;
    st.flags = ST_SELECTION;
    SendMessageW(hRichEdit, EM_SETTEXTEX, (WPARAM)&st, (LPARAM)rtf.c_str());

    // 获取纯文本长度并提取
    int textLen = SendMessageW(hRichEdit, WM_GETTEXTLENGTH, 0, 0) + 1;
    std::wstring plainText(textLen, L'\0');
    SendMessageW(hRichEdit, WM_GETTEXT, (WPARAM)textLen, (LPARAM)plainText.data());

    // 清理窗口
    DestroyWindow(hRichEdit);

    // 去除末尾多余空白字符
    plainText.erase(std::find_if(plainText.rbegin(), plainText.rend(), 
        [](wchar_t c) { return !iswspace(c); }).base(), plainText.end());

    return plainText;
}

// 使用示例
std::wstring sString = L"{\\rtf1\\ansi\\ansicpg1252\\deff0\\nouicompat\\deflang2057{\\fonttbl{\\f0\\fnil\\fprq12\\fcharset0 Times New Roman;}}\r\n{\\*\\generator Riched20 10.0.19041}\\viewkind4\\uc1 \r\n\\pard\\f0\\fs24 HELLO\\par\r\n}\\r\n";
std::wstring plainText = extractRTFWithRichEdit(sString);
// plainText 结果为 L"HELLO"

内容的提问来源于stack exchange,提问作者Олександр Дрожжин

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 04:42:47