如何从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控件是最稳妥的方案,步骤如下:
- 加载
Msftedit.dll库 - 创建隐藏的RichEdit窗口
- 向控件传入RTF内容
- 从控件中提取纯文本
示例代码:
#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,提问作者Олександр Дрожжин
相关产品推荐
相关产品推荐

