【问题标题】:Glue strings without 3rd string没有第三根绳子的胶水绳子
【发布时间】:2026-01-15 12:05:01
【问题描述】:

我有两个字符串,我需要用boost::regex 将它们解析为一个。为了实现这一点,我需要将我的字符串粘在一些 boost::string_ref 之类的对象中,但是不允许进行额外分配

换句话说,我需要这样的东西。

const char s1[] = "abcd<ht";
const char s2[] = "ml>giuya";

boost::regex e("<[^>]*>");

//this is what i'm looking for
auto glued_string = make_glued_string(s1, sizeof(s1)-1,
                                      s2, sizeof(s2)-1); 

boost::regex_iterator<glue_string::iterator> 
    it(glued_string.begin(), glued_string.end(), e, 
    boost::match_default | boost::match_partial);

所以问题是有没有合适的库或者我必须自己实现?谢谢。

【问题讨论】:

  • 您似乎正在尝试使用正则表达式解析某种类似 HTML 的语法。请参考this answer.
  • 谢谢,但这只是一个例子。我的任务确实需要正则表达式。
  • boost::range::join 应该可以工作(尽管我指出了错误的版本)。看到这个问题:*.com/questions/14366576/…
  • 这个好像是我需要的,谢谢,我试试

标签: c++ regex string boost


【解决方案1】:
#include <string>
#include <iostream>

#include <boost/range/adaptor/indexed.hpp>
#include <boost/range/join.hpp>
#include <boost/regex.hpp>

const char s1[] = "abcd<ht";
const char s2[] = "ml>giuya";

int main() {
    auto glued = boost::range::join(
        s1 | boost::adaptors::indexed(0),
        s2 | boost::adaptors::indexed(0));
    std::cout << "glued: ";
    for (auto c : glued)
        std::cout << c;
}

【讨论】:

  • 这是用于融合向量.. 不适用于字符串
  • 替换为正确的 boost::range::join (并经过测试)
【解决方案2】:

这是您的答案 - 100% 高效(ish)。

为了防止早期批评,复制几乎总是比引用链更快。

#include <iostream>
#include <string>
#include <type_traits>

using namespace std;

template<typename T1, int N1, typename T2, int N2>
string glue_string(T1 (&src1)[N1], T2 (&src2)[N2])
{
    string s(begin(src1), end(src1));
    s.insert(end(s), begin(src2), end(src2));
    return s;
}

int main()
{
    const char s1[] = "Hello, ";
    const char s2[] = "World";
    cout << glue_string(s1,s2) << endl; 

   return 0;
}

但你不确定你不是真的想要这个:

#include <iostream>
#include <iterator>

const char src[] = "Hello,"
" World";

using namespace std;

int main()
{
    auto first = begin(src);
    auto last = end(src);
    for( ; first != last ; ++first)
        cout.put(*first);
    return 0;
}

字符串连接由编译器完成 - 字符串的零副本,因为如果编译器知道长度,c++11 begin() 和 end() 可以在 c 样式数组上工作。

【讨论】:

  • 我需要将两个字符串作为一个传递给 boost::regex.. 并且不允许额外的分配。请在回答之前仔细阅读。
  • “复制几乎总是更快”的说法似乎很荒谬。它取决于(并且仅取决于)使用模式,因为链接避免了 - 分配! - 在许多情况下可以轻松支配运行时成本。
  • 这是违反直觉的,但并不荒谬。涉及链接迭代器对的解决方案需要为每个字符串部分(开始和结束)存储至少 2 个指针。那是 8 或 16 个字节,具体取决于架构。所以在上面的例子中,boost::join 的结果将产生一个包含至少 4 个指针的结构,加上一个字符串间迭代器和一个字符串内迭代器。即至少 24 个字节。使用 SSO(短字符串优化),您会发现 std::string 解决方案可能至少同样有效。
最近更新 更多