使用像std :: find()这样的算法函数会有更好的方法吗?
std::string s = "012X012Y012";
//After erasing the numbers from beginning and end; the end result should be X012Y
size_t index = s.find_first_not_of("0123456789");
string::iterator iter_end = s.begin();
advance(iter_end, index);
s.erase(s.begin(), iter_end);
//Now std::string should be X012Y012
size_t index = s.find_last_not_of("0123456789")+1;
string::iterator iter_start = s.begin();
advance(iter_start, index);
s.erase(iter_start, s.end());
//Finally, std::string should be X012Y
Run Code Online (Sandbox Code Playgroud)
看起来很好.我会把你的常数分解出来:
const std::string Numbers = "0123456789";
Run Code Online (Sandbox Code Playgroud)
并重新使用它.erase
允许您使用索引而不是迭代器,因此您可以从代码中修剪所有迭代器内容.你还应该检查你的搜索结果,否则你会对你的字符串做一些奇怪的事情:
std::size_t start = s.find_first_not_of(Numbers);
if (start != std::string::npos)
s.erase(0, start);
size_t end = s.find_last_not_of(Numbers);
if (end != std::string::npos)
s.erase(end + 1, std::string::npos);
Run Code Online (Sandbox Code Playgroud)
最后,我认为你应该在左前方修剪右边.如果先修剪左边,erase
则需要复制和移动字符串的其余部分.通过首先修剪右边,你可以消除一些要复制的东西.我怀疑,没什么大不了的,但不妨.
(对于大多数序列容器来说都是如此:从某个点到最终的擦除只是意味着摆脱对象,而从开始到某个点的擦除需要将剩余的项目移动到新的位置.)
当然,您可以对此进行概括并重新使用它:
// typically you trim whitespace, so for the sake of
// a generic utility, default to that
const std::string whitespace = " \f\n\r\t\v";
void trim_left(std::string& pStr, const std::string& pExcess = whitespace)
{
std::size_t start = s.find_first_not_of(pExcess);
if (start != std::string::npos)
s.erase(0, start);
}
void trim_right(std::string& pStr, const std::string& pExcess = whitespace)
{
size_t end = s.find_last_not_of(pExcess);
if (end != std::string::npos)
s.erase(end + 1, std::string::npos);
}
void trim(std::string& pStr, const std::string& pExcess = whitespace)
{
// right then left, for reasons said above
trim_right(pStr, pExcess);
trim_left(pStr, pExcess);
}
Run Code Online (Sandbox Code Playgroud)