代码之家  ›  专栏  ›  技术社区  ›  Dominic Rodger

在C++中用明文生成HTML(即BR和P标签)

  •  1
  • Dominic Rodger  · 技术社区  · 15 年前

    我有一大堆这样的文字:

    foo
    bar
    
    baz
    

    什么是最有效的方式在C++中转化为:

    <p>foo<br />bar</p>
    <p>baz</p>
    

    用于大量(ish)文本(最多8000个字符)。

    regex_replace \n\n 可能更有效?有什么想法吗?还有其他方法吗?

    大多数第三方库在我工作的环境中都不可用。

    4 回复  |  直到 15 年前
        1
  •  5
  •   Peter Mortensen John Conde    15 年前

    通过循环每次比较状态,但 这应该无关紧要(可以通过使用sub 循环处于第三种状态-请参见下文)。启动状态将为 将是前一个字符的变量,另一个用于 生成输出)。

    • 遇到双新线。进入状态时的操作:输出<p>,线路和</p>


    • 遇到正常字符

    这个程序看起来更像一个C程序,不过。。。

        2
  •  2
  •   Brian Agnew    15 年前

    foo&
    

    您需要对其进行适当的翻译:

    foo&amp;
    

    (不知道你是否意识到——只是没有被提及,而且经常被忘记!)

        3
  •  1
  •   Vinay Sajip    15 年前

    如果您的数据不包含意外情况,则可以替换 \n\n 具有 </p><p> ,然后更换所有 \n <br/> . 然后用括号将结果括起来 <p> </p> ,你就完了。这不处理边缘情况(例如,三个分隔段落的换行符),但它非常简单,并且比编写状态机更快!

    更新: 显然,如果你有 \n\n\n , \n\n\n\n 等等,然后你也可以用 </p>&书信电报;p>

        4
  •  0
  •   Adrian McCarthy    15 年前

    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;
    }