从std :: string的开头和结尾删除数字

cpx*_*cpx 1 c++

使用像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)

GMa*_*ckG 5

看起来很好.我会把你的常数分解出来:

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)