简体   繁体   English

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

[英]Erasing numbers from beginning and end of std::string

Would there be a better way to do this using alogrithm functions like std::find()? 使用诸如std :: find()之类的alogrithm函数,会有更好的方法吗?

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

Seems fine enough. 似乎足够好。 I'd factor out your constant: 我会把你的常数排除在外:

const std::string Numbers = "0123456789";

And re-use that. 并重复使用。 erase does allow you to use indices instead of iterators, so you can trim all that iterator stuff from your code. erase确实允许您使用索引而不是迭代器,因此您可以从代码中修剪所有迭代器内容。 You should also check the results of your search, otherwise you'll do weird things to your string: 您还应该检查搜索结果,否则会对字符串做奇怪的事情:

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);

Lastly, I think you should trim the right before the left. 最后,我认为您应该在左边之前修剪右边。 If you trim the left first, during erase the remainder of the string needs to be copied and moved down. 如果先修剪左侧,则在erase过程中,需要复制其余字符串并向下移动。 By trimming the right first, you eliminate some things to copy. 通过首先裁切正确的内容,可以消除要复制的内容。 Nothing major, I suspect, but might as well. 我怀疑没有什么大不了的,但也有可能。

(This is true of most sequence containers: erasing from some point to the end simply means getting rid of objects, while erasing from the start to some point requires moving the remaining items into their new spot.) (对于大多数序列容器而言,这都是正确的:从某个点到最后进行擦除只是意味着摆脱对象,而从开始到某个点进行擦除则需要将其余项目移到新位置。)


Of course, you can generalize this and re-use it: 当然,您可以对此进行概括并重新使用:

// 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);
}

Not a pure STL solution, but the Boost String libraries make this trivial: 这不是一个纯粹的STL解决方案,但是Boost String库使这个琐碎的事:

std::string s = "012X012Y012";
boost::trim_if(s, boost::is_digit());
std::cout << s << std::endl; // Outputs: "X012Y"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM