简体   繁体   中英

Replace a pattern in C++ 98

I need to do in place replacement in a string for a specific pattern Example:

Input:

temp.temp2..temp3....temp4......temp5

Output:

temp.temp2.temp3.temp4.temp5

So basically if it is single dot, leave as it is , but if there are more consecutive dots, replace them with a single dot.

I tried iterating the string and copying into another string objects based on comparisons, and it looks real ugly now. I wonder any better way using C++ STL?

You can use boost regex if you need to stick with C++98.

#include <boost/regex.hpp>
#include <iostream>

int main()
{
    std::string str = "....";
    boost::regex re("\\.{2,}");
    std::cout << regex_replace(str, re, ".") << std::cout;
}

If you can not use boost, the simplest solution I have in mind is this:

#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;
}

the algorithm shouldn't be long or ugly. it's supposed to be simple and clean.

psuedo-code

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 '.'  

real C++ example :

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

can be run here : http://coliru.stacked-crooked.com/a/aa6923d4049a1fdd

This is a trivial task.

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

With C++11, you could replace the ugly dst[dst.size() - 1] with dst.back() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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