How can I implement efficient replacement of whole words in C ++ without regular expressions?

Maybe I'm losing sight of something obvious, but I was wondering what might be the fastest way to implement replacing whole words with C ++. At first, I looked at just concatenating spaces in a search word, but that doesn't take into account line boundaries or punctuation marks.

This is my current abstraction to replace (not a whole word):

void Replace(wstring& input, wstring find, wstring replace_with) {
  if (find.empty() || find == replace_with || input.length() < find.length()) {
      return;
  }
  for (size_t pos = input.find(find); 
              pos != wstring::npos; 
              pos = input.find(find, pos)) {

      input.replace(pos, find.length(), replace_with);
      pos += replace_with.length();
  }
}

If I consider spaces as the boundary of a word, I could implement this by comparing the beginning and end of the search string with the search string to cover the borders of the strings, and then follow with the replacement (L '' + find + L '') .... but I was wondering if there was a more elegant solution that would effectively include punctuation.

, ( , !) # $% & '() * +, -./at minimum - (c > 31 && c < 48)).

, Unicode, . , STL .

- , , .

+5
2

, , , . :

  • " ", "std:: isalpha", Unicode .
  • " ", "output", "" , , " " "input".

:

#include <cctype> // isalpha
#include <ciso646> // or, not
#include <string> // wstring

using std::size_t;
using std::wstring;

/// @brief Do a "find and replace" on a string.
/// @note This function does "whole-word" matching.
/// @param[in,out] input_string The string to operate on.
/// @param[in] find_string The string to find in the input.
/// @param[in] replace_string The string to replace 'find_string'
///            with in the input.
void find_and_replace( wstring& input_string,
                       const wstring& find_string,
                       const wstring& replace_string )
{
  if( find_string.empty()
      or find_string == replace_string
      or input_string.length() < find_string.length() )
  {
    return;
  }

  wstring output_string;
  output_string.reserve( input_string.length() );
  size_t last_pos = 0u;
  for( size_t new_pos = input_string.find( find_string );
       new_pos != wstring::npos;
       new_pos = input_string.find( find_string, new_pos ) )
  {
    bool did_replace = false;
    if( ( new_pos == 0u
          or not std::isalpha( input_string.at( new_pos - 1u ) ) )
        and ( new_pos + find_string.length() == input_string.length()
              or not std::isalpha( input_string.at( new_pos + find_string.length() ) ) ) )
    {
      output_string.append( input_string, last_pos, new_pos - last_pos );
      output_string.append( replace_string );
      did_replace = true;
    }
    new_pos += find_string.length();
    if( did_replace )
    {
      last_pos = new_pos;
    }
  }
  output_string.append( input_string, last_pos,
                        input_string.length() - last_pos );

  input_string.swap( output_string );
}

P.S. , "replace_all" , .

P.P.S. Regex-es. ++ TR1 ++ 2011? regex.

+2

, , ... :
1. , ( ), :

string& remove_all_occurences(string& s, const string& str_to_remove, const string& str_to_put){
                typedef string::size_type string_size;
                string_size i = 0;
                string cur_string;
                cur_string.reserve(s.size());

                // invariant: we have processed characters [original value of i, i) 
                while (i != s.size()) {
                // ignore leading blanks
                // invariant: characters in range [original i, current i) are all spaces
                    while (i != s.size() && isspace(s[i]))
                    ++i;

                    // find end of next word
                    string_size j = i;
                    // invariant: none of the characters in range [original j, current j)is a space
                     while (j != s.size() && !isspace(s[j]))
                        j++;
                        // if we found some nonwhitespace characters 


                    if (i != j) {
                        // copy from s starting at the beginning to i, placing str to replace, and finishing with j to the end of s
                        cur_string = s.substr(i,j-i);
                        if(cur_string == str_to_remove){
                            s = s.substr(0,i) + str_to_put + s.substr(j,s.size() - j);
                        }
                        i = j;
                    }
                }
                return s;
            }

:

void call_remove_all_occurences(){
                string my_str = "The quick brown fox jumps over sleepy dog fox fox fox";
                cout << remove_all_occurences(my_str,"fox","godzilla") << endl;
            }

:

The quick brown godzilla jumps over sleepy dog godzilla godzilla godzilla
  • - ... , ...
+1

All Articles