在 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 - &lt;br /&gt; 而不是 &lt;br&gt;&lt;br&gt; 将是无效的 Xhtml 很抱歉听到三个换行符 - 我更新了我的答案。 为此目的制作一个 awk 或 perl 脚本。 我不相信这些建议(截至 2011 年 2 月 15 日)中的任何一个都考虑了空格。假设您的 HTML 以典型的white-space 解释显示,那么输入中以多个空格或制表符开头的行,或者它们之间有很大间隔的单词的行将被忽略。 【参考方案1】:

我会使用一个简单的状态机。它确实需要 通过循环比较每次的状态,但是 没关系(它可以通过有一个子来优化 在第三个状态循环 - 见下文)。开始状态将 与遇到两个换行符时相同。那里 将是前一个字符的变量和一个 跟踪最后一个换行符的位置(用于 生成输出)。

状态将是:

遇到双新行。进入状态时的动作:

、行、

的输出

遇到一个新行。进入状态时的动作:行的输出和

遇到正常字符

该程序看起来更像是一个 C 程序,不过...

【讨论】:

+1 - 得到了这个工作的一个简单版本(虽然我已经稍微调整了它 - 从按下

开始,开始状态是“没有遇到换行符”。遇到换行符我设置“遇到换行符”,除非它已经设置,此时我取消设置,然后按下

。如果遇到非换行符 x,我按下 x,然后取消设置“遇到换行符”。但是,我认为 Vinay 的答案可能会更快更容易管理。

【参考方案2】:

不要忘记为 HTML 实体编码您的文本!例如如果你有

foo&

你需要适当地翻译它:

foo&amp;

(不知道你是否知道 - 它只是没有被提及并且经常被遗忘!)

【讨论】:

【参考方案3】:

如果您的数据没有意外,您只需将所有\n\n 实例替换为&lt;/p&gt;&lt;p&gt;,然后将所有\n 替换为&lt;br/&gt;。然后将结果用&lt;p&gt;&lt;/p&gt; 括起来,就完成了。这不处理边缘情况(例如,三个换行符分隔段落),但它非常简单,并且比编写状态机更快!

更新:显然,如果您有\n\n\n\n\n\n\n 等,那么您也可以将它们替换为&lt;/p&gt;&lt;p&gt;,首先从较长的序列开始。

【讨论】:

+1 - 看起来效果很好而且速度很快 - 谢谢。出于某种原因,我没有想到(现在看起来很明显)解决方案。 可悲的是,我的很多输入都有三个换行符分隔段落。哦! 我想知道regex_replace 是否更适合用&lt;/p&gt;&lt;p&gt; 替换较长的\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 注入

如何在 VIsual Studio 2013 中从 UML 图生成 C++ 代码

如何在html中从下到上设置垂直文本?

从纯文本文件中细化和构建 csv 文件

富文本编辑器中<br/>啥操作

在 PHP 中从文本创建图像 - 如何制作多行?