替换 C++ 98 中的模式
Replace a pattern in C++ 98
我需要在字符串中针对特定模式进行就地替换
示例:
输入:
temp.temp2..temp3....temp4......temp5
输出:
temp.temp2.temp3.temp4.temp5
所以基本上如果是单点,就保持原样,但是如果有更多连续的点,将它们替换为单点。
我尝试迭代字符串并根据比较复制到另一个字符串对象中,现在看起来真的很难看。
我想知道使用 C++ STL 有什么更好的方法吗?
如果你需要坚持使用 C++98,你可以使用 boost 正则表达式。
#include <boost/regex.hpp>
#include <iostream>
int main()
{
std::string str = "....";
boost::regex re("\.{2,}");
std::cout << regex_replace(str, re, ".") << std::cout;
}
如果你不能使用boost,我想到的最简单的解决方案是:
#include <iostream>
#include <sstream>
using namespace std;
string replaceConsecutiveDots(const string& str) {
std::stringstream ss;
bool previousCharIsDot = false;
for (string::const_iterator it = str.begin(); it!=str.end(); ++it) {
char c = *it;
if (c != '.' || !previousCharIsDot) {
ss << c;
}
previousCharIsDot = c == '.';
}
return ss.str();
}
int main() {
string str = "temp.temp2..temp3....temp4......temp5";
cout << replaceConsecutiveDots(str) << endl;
}
算法不应该太长或太难看。它应该简单干净。
伪代码
from pos 0 to string.length -1
do
if string[pos] is '.'
if string[pos+1] is '.'
do
erase string[pos+1] while string[pos+1] is '.'
真实的 C++ 示例:
void cleanStringDots(string& str){
for (int i=0;i<str.size()-1;i++){
if (str[i] == '.' && str[i+1] == '.'){
size_t count = 1;
for (int j = i+2; j<str.size() && str[j] =='.';j++){
if (str[j]=='.') {
count++;
}
}
str.erase(i+1,count);
}
}
}
int main(){
string str = "temp.temp2..temp3....temp4......temp5";
cleanStringDots(str);
cout<<str;
}
可以是 运行 这里:http://coliru.stacked-crooked.com/a/aa6923d4049a1fdd
这是一项微不足道的任务。
std::string convert(const std::string& src) {
std::string dst;
for (std::string::size_type i = 0; i < src.size(); ++i) {
if (src[i] == '.' && dst.size() && dst[dst.size() - 1] == '.') continue;
dst.push_back(src[i]);
}
return dst;
}
使用 C++11,您可以将丑陋的 dst[dst.size() - 1]
替换为 dst.back()
。
我需要在字符串中针对特定模式进行就地替换 示例:
输入:
temp.temp2..temp3....temp4......temp5
输出:
temp.temp2.temp3.temp4.temp5
所以基本上如果是单点,就保持原样,但是如果有更多连续的点,将它们替换为单点。
我尝试迭代字符串并根据比较复制到另一个字符串对象中,现在看起来真的很难看。 我想知道使用 C++ STL 有什么更好的方法吗?
如果你需要坚持使用 C++98,你可以使用 boost 正则表达式。
#include <boost/regex.hpp>
#include <iostream>
int main()
{
std::string str = "....";
boost::regex re("\.{2,}");
std::cout << regex_replace(str, re, ".") << std::cout;
}
如果你不能使用boost,我想到的最简单的解决方案是:
#include <iostream>
#include <sstream>
using namespace std;
string replaceConsecutiveDots(const string& str) {
std::stringstream ss;
bool previousCharIsDot = false;
for (string::const_iterator it = str.begin(); it!=str.end(); ++it) {
char c = *it;
if (c != '.' || !previousCharIsDot) {
ss << c;
}
previousCharIsDot = c == '.';
}
return ss.str();
}
int main() {
string str = "temp.temp2..temp3....temp4......temp5";
cout << replaceConsecutiveDots(str) << endl;
}
算法不应该太长或太难看。它应该简单干净。
伪代码
from pos 0 to string.length -1
do
if string[pos] is '.'
if string[pos+1] is '.'
do
erase string[pos+1] while string[pos+1] is '.'
真实的 C++ 示例:
void cleanStringDots(string& str){
for (int i=0;i<str.size()-1;i++){
if (str[i] == '.' && str[i+1] == '.'){
size_t count = 1;
for (int j = i+2; j<str.size() && str[j] =='.';j++){
if (str[j]=='.') {
count++;
}
}
str.erase(i+1,count);
}
}
}
int main(){
string str = "temp.temp2..temp3....temp4......temp5";
cleanStringDots(str);
cout<<str;
}
可以是 运行 这里:http://coliru.stacked-crooked.com/a/aa6923d4049a1fdd
这是一项微不足道的任务。
std::string convert(const std::string& src) {
std::string dst;
for (std::string::size_type i = 0; i < src.size(); ++i) {
if (src[i] == '.' && dst.size() && dst[dst.size() - 1] == '.') continue;
dst.push_back(src[i]);
}
return dst;
}
使用 C++11,您可以将丑陋的 dst[dst.size() - 1]
替换为 dst.back()
。