最简单的方法是使用正则表达式库:
#include <iostream>
#include <regex>
int main()
{
std::string myString = R"svg(
<svg height={size} width={size}>
<rect {...rectProps} x={x0h} y={y0h} />
// <rect {...rectProps} x={x1h} y={y0h} />
<rect {...rectProps} x={x0h} y={y1h} />
// <rect {...rectProps} x={x1h} y={y1h} />
</svg>
)svg";
std::cout << myString << std::endl; //before
std::string new_string = std::regex_replace(myString, std::regex("\n *//.*\n"), "\n");
std::cout << new_string << std::endl; //after
}
我们捕获所有以新行
\n
开头、具有零个或多个空格 *
、两个斜杠 //
以及零个或多个以另一新行结尾的任何字符 .*
的模式。我们仅用一个新行替换出现的事件(以补偿其中一个)。
输出:
<svg height={size} width={size}>
<rect {...rectProps} x={x0h} y={y0h} />
// <rect {...rectProps} x={x1h} y={y0h} />
<rect {...rectProps} x={x0h} y={y1h} />
// <rect {...rectProps} x={x1h} y={y1h} />
</svg>
<svg height={size} width={size}>
<rect {...rectProps} x={x0h} y={y0h} />
<rect {...rectProps} x={x0h} y={y1h} />
</svg>
基于 std::basic_string::find_first_not_of 找到的
'/'
的数量使用 std::basic_string::erase 的简单性很难被击败,例如
std::string s { "//Some comment" };
if (s.at(0) == '/')
s.erase (0, s.find_first_not_of ("/"));
您还可以通过将
"//"
添加到拒绝字符来删除 " \t"
之前的任何前导空格:
std::string s { " //Some comment" };
if (s.at(s.find_first_not_of (" \t/") - 1) == '/')
s.erase (0, s.find_first_not_of (" \t/"));
(注意:
- 1
与 at()
是必需的,因为它需要从零开始的索引,而 erase()
需要删除字符数)
然后要处理
"//"
周围的前导和尾随空白,您可以 #include <cctype>
并使用 isspace(c)
,如下所示:
std::string s { " // Some comment" };
char c = s.at(s.find_first_not_of (" \t/") - 1);
if (c == '/' || isspace (c))
s.erase (0, s.find_first_not_of (" \t/"));
在所有情况下,结果都是
"Some comment"
。
没有按我的预期工作
除了它之外,它绝对不会按照你的方式工作。 您使用的
erase
的过载看起来像
string& erase( size_type index = 0, size_type count = npos);
来自 cppreference 的重载描述:
删除从索引开始的 min(count, size() - index) 个字符。
所以你真正做的
svg.erase(0, svg.find("//") + 1)
是删除从索引[0]到[你找到的最后一个'/'
的索引]的所有字符
相反,您应该执行以下操作:
"//"
,将此位置命名为 A。'\n'
,将此位置命名为 B。P.s.我建议从末尾而不是从头开始搜索,因为如果它更接近末尾而不是开头,则擦除片段形式的字符串会更容易
P.p.s.如果您想精确删除间隔,请务必使用迭代器,因为删除间隔的
erase
的唯一重载是
iterator erase( const_iterator first, const_iterator last );
最后这就是我找到的解决方案
std::string trim(const std::string &str) {
size_t first = str.find_first_not_of(' ');
if (std::string::npos == first) {
return str;
}
size_t last = str.find_last_not_of(' ');
return str.substr(first, (last - first + 1));
}
bool startsWith(const std::string &input, const std::string &start) {
return input.find(start) != std::string::npos;
}
std::string myString = R"svg(
<svg height={size} width={size}>
<rect {...rectProps} x={x0h} y={y0h} />
// <rect {...rectProps} x={x1h} y={y0h} />
<rect {...rectProps} x={x0h} y={y1h} />
// <rect {...rectProps} x={x1h} y={y1h} />
</svg>
)svg";
std::istringstream stream(myString);
std::string line;
std::string myFinalString;
while (std::getline(stream, trim(line))) {
if (!startsWith(line, "//")) {
myFinalString += line + "\n";
}
}