【发布时间】:2012-01-11 19:44:47
【问题描述】:
我将如何在c++ 中执行类似于以下代码的操作:
//Lang: Java
string.replaceAll(" ", " ");
此代码-sn-p 会将字符串中的所有多个空格替换为单个空格。
【问题讨论】:
我将如何在c++ 中执行类似于以下代码的操作:
//Lang: Java
string.replaceAll(" ", " ");
此代码-sn-p 会将字符串中的所有多个空格替换为单个空格。
【问题讨论】:
bool BothAreSpaces(char lhs, char rhs) { return (lhs == rhs) && (lhs == ' '); }
std::string::iterator new_end = std::unique(str.begin(), str.end(), BothAreSpaces);
str.erase(new_end, str.end());
这是如何工作的。 std::unique 有两种形式。第一种形式通过一个范围并删除相邻的重复项。所以字符串“abbaaabbbb”变成了“abab”。我使用的第二种形式采用一个谓词,该谓词应该采用两个元素,如果它们应该被视为重复元素,则返回 true。我写的函数BothAreSpaces 就是为了这个目的。它确切地确定了它的名字所暗示的内容,它的两个参数都是空格。所以当与std::unique结合时,重复的相邻空格会被删除。
就像std::remove 和remove_if 一样,std::unique 实际上并没有使容器变小,它只是将末尾的元素移动到更靠近开头的位置。它返回一个指向新范围末尾的迭代器,因此您可以使用它来调用erase 函数,该函数是字符串类的成员函数。
分解它,擦除函数有两个参数,一个开始迭代器和一个结束迭代器,用于擦除一个范围。对于它的第一个参数,我传递了std::unique 的返回值,因为这是我要开始擦除的地方。对于它的第二个参数,我传递了字符串的结束迭代器。
【讨论】:
template<char Remove> bool BothAre(char lhs, char rhs) { return lhs == rhs && lhs == Remove; } 然后str.erase(std::unique(str.begin(), str.end(), BothAre<' '>), str.end()); 让它有点通用,也可以用于其他角色
std::unique 将接收到的两个迭代器之间的所有连续重复字符移动到 end 迭代器,以便所有字符都位于字符串的末尾。然后它将迭代器返回到它移动到字符串末尾的所有字符的开头,并将该迭代器传递给str.erase,它需要两个迭代器并删除它们之间的所有字符。 tl;dr:所有重复的空格都通过unique 出现在字符串的末尾,然后erase 将它们删除。
std::remove 都不需要这样做,而且我不知道他们有任何实现。他们只是将非重复元素从末端复制或移动到前面。
所以,我尝试了一种使用 std::remove_if 和 lambda 表达式的方法——尽管在我看来它似乎仍然比上面的代码更容易理解,但它没有那种“哇,真棒,没想到你能做到这一点” 事情到它..无论如何我仍然发布它,如果只是为了学习目的:
bool prev(false);
char rem(' ');
auto iter = std::remove_if(str.begin(), str.end(), [&] (char c) -> bool {
if (c == rem && prev) {
return true;
}
prev = (c == rem);
return false;
});
in.erase(iter, in.end());
EDIT 意识到 std::remove_if 返回一个可以使用的迭代器.. 删除了不必要的代码。
【讨论】:
Benjamin Lindley 答案的变体,它使用 lambda 表达式使事情变得更简洁:
std::string::iterator new_end =
std::unique(str.begin(), str.end(),
[=](char lhs, char rhs){ return (lhs == rhs) && (lhs == ' '); }
);
str.erase(new_end, str.end());
【讨论】:
为什么不使用正则表达式:
boost::regex_replace(str, boost::regex("[' ']{2,}"), " ");
【讨论】:
regex 库,如果使用 boost 有问题,可以使用它。
isspace(lhs) && isspace(rhs) 处理所有类型的空格怎么样
【讨论】: