【问题标题】:Remove substring from both ends of an std::string?从 std::string 的两端删除子字符串?
【发布时间】:2019-10-21 11:32:37
【问题描述】:

我正在尝试删除 std::string 中的一些开始和结束分隔符。有没有内置的或更好的方法来做到这一点?

这是我目前的方式:

std::string sub = "~test.txt~";
std::string str = "~test.txt~The quick brown fox jumps over the lazy dog.~test.txt~";

str = str.substr(sub.length(), str.length() - sub.length() * 2);

开始和结束分隔符完全相同,并且位于最边缘。

预期值为The quick brown fox jumps over the lazy dog.

【问题讨论】:

  • 删除前是否需要检查前缀/后缀?
  • @Jarod42 开始和结束分隔符是相同的,并且总是位于最末端。更新了我的问题供其他人查看。

标签: c++ string substring


【解决方案1】:

您的代码的唯一问题是.substr() 创建了一个新的std::string,导致分配昂贵(除非结果小到足以让 SSO 工作)。

使用std::string_view 来解决这个问题:

str = std::string_view(str).substr(sub.length(), str.length() - sub.length() * 2);

或者,使用.assign():

str.assign(str.begin() + sub.length(), str.end() - sub.length());

【讨论】:

  • 感谢您的建议,尽管我现在只使用 C++11。但我肯定也会尝试.assign()
【解决方案2】:

你所拥有的是正确的(对于这种受限的情况)和高效的(假设你需要一个 std::string 结果;如果你使用 C++17,std::string_view 可能会很好)。如果它很难看,就让它成为一个函数,以便其余代码可以使用

std::string mid=remove2(whole, delim);

...虽然在

的情况下这不是有效的
remove2(whole, "literal")

它分配内存只是为了计算在编译时已知数量的字符。如果这很重要,您可以添加一个需要一定长度的重载并写入

remove2(whole, sizeof("literal")-1)

【讨论】:

  • 不必要的额外分配肯定不是高效
  • @Deduplicator:为什么叫它extra?我们不知道创建的 string 是否用于不支持指针/长度对的东西。 (例如,源可能已经是const std::string,结果可以与const char* 一起使用。)
  • 考虑到没有任何分配的解决方案,一个分配是“额外的”。
  • @Deduplicator:展示如何在不分配或写入原始文件的情况下将结果作为 NTBS 获得,我们已经准备好了。
  • @Davis:现在你正在移动球门柱。
猜你喜欢
  • 2019-03-22
  • 2020-09-02
  • 2014-01-25
  • 1970-01-01
  • 1970-01-01
  • 2019-09-08
  • 1970-01-01
相关资源
最近更新 更多