在 C++ 中从纯文本生成 HTML(即 br 和 p 标签)
Posted
技术标签:
【中文标题】在 C++ 中从纯文本生成 HTML(即 br 和 p 标签)【英文标题】:Generating HTML (i.e. br and p tags) from plaintext in C++ 【发布时间】:2009-09-07 08:09:32 【问题描述】:我有一堆这样的文字:
foo
bar
baz
在 C++ 中将其转换为此的最有效方式可能是:
<p>foo<br />bar</p>
<p>baz</p>
用于大量(ish)文本(最多 8000 个字符)。
我很高兴使用 boost 的 regex_replace
,但我想知道字符串搜索 \n\n
是否可能更有效?有什么想法吗?还有其他方法吗?
在我工作的环境中,我无法使用大多数第三方库。
【问题讨论】:
呃……空的 元素是怎么回事? @unwind -<br />
而不是 <br>
? <br>
将是无效的 Xhtml。
很抱歉听到三个换行符 - 我更新了我的答案。
为此目的制作一个 awk 或 perl 脚本。
我不相信这些建议(截至 2011 年 2 月 15 日)中的任何一个都考虑了空格。假设您的 HTML 以典型的white-space
解释显示,那么输入中以多个空格或制表符开头的行,或者它们之间有很大间隔的单词的行将被忽略。
【参考方案1】:
我会使用一个简单的状态机。它确实需要 通过循环比较每次的状态,但是 没关系(它可以通过有一个子来优化 在第三个状态循环 - 见下文)。开始状态将 与遇到两个换行符时相同。那里 将是前一个字符的变量和一个 跟踪最后一个换行符的位置(用于 生成输出)。
状态将是:
遇到双新行。进入状态时的动作:
、行、
的输出遇到一个新行。进入状态时的动作:行的输出和
遇到正常字符
该程序看起来更像是一个 C 程序,不过...
【讨论】:
+1 - 得到了这个工作的一个简单版本(虽然我已经稍微调整了它 - 从按下开始,开始状态是“没有遇到换行符”。遇到换行符我设置“遇到换行符”,除非它已经设置,此时我取消设置,然后按下
。如果遇到非换行符 x,我按下 x,然后取消设置“遇到换行符”。但是,我认为 Vinay 的答案可能会更快更容易管理。
【参考方案2】:不要忘记为 HTML 实体编码您的文本!例如如果你有
foo&
你需要适当地翻译它:
foo&
(不知道你是否知道 - 它只是没有被提及并且经常被遗忘!)
【讨论】:
【参考方案3】:如果您的数据没有意外,您只需将所有\n\n
实例替换为</p><p>
,然后将所有\n
替换为<br/>
。然后将结果用<p>
和</p>
括起来,就完成了。这不处理边缘情况(例如,三个换行符分隔段落),但它非常简单,并且比编写状态机更快!
更新:显然,如果您有\n\n\n
、\n\n\n\n
等,那么您也可以将它们替换为</p><p>
,首先从较长的序列开始。
【讨论】:
+1 - 看起来效果很好而且速度很快 - 谢谢。出于某种原因,我没有想到(现在看起来很明显)解决方案。 可悲的是,我的很多输入都有三个换行符分隔段落。哦! 我想知道regex_replace
是否更适合用</p><p>
替换较长的\n\n...
序列。【参考方案4】:
紧凑、快速、丑陋的状态机。处理退化的情况,例如空输入、输入开头的空行、段落之间的长空行字符串以及输入末尾缺少的换行符。
template <typename InputIt, typename OutputIt>
void TextToHTML(InputIt begin, InputIt end, OutputIt target)
start: if (begin == end) return;
if (*begin == '\n') ++begin; goto start;
*target++ = '<'; *target++ = 'p'; *target++ = '>';
para: *target++ = *begin++;
if (begin == end) goto endp;
if (*begin != '\n') goto para;
if (++begin == end) goto endp;
if (*begin == '\n') goto endp;
*target++ = '<'; *target++ = 'b'; *target++ = 'r'; *target++ = ' '; *target++ = '/'; *target++ = '>';
goto para;
endp: *target++ = '<'; *target++ = '/'; *target++ = 'p'; *target++ = '>'; *target++ = '\n';
goto start;
int main()
std::string text = "foo\nbar\n\nbaz";
std::string html;
TextToHTML(text.begin(), text.end(), std::back_inserter(html));
std::cout << html << std::endl;
return 0;
【讨论】:
以上是关于在 C++ 中从纯文本生成 HTML(即 br 和 p 标签)的主要内容,如果未能解决你的问题,请参考以下文章
vue js - 从纯文本到 vue 组件的 HTML 注入