String/text manipulation utility class I'd like to get some expert's view on this first piece of code especially in the area of

performance - (e.g. avoidable copies)
good practice (e.g. static members?)

The final goal is the provide some abstractions for text manipulation like cleansing, stop-word removal and tokenization. The code base should grow substantially in the future so a lot more string manipulation methods should be supported. I understand that this should be bundled in a library in the end, however, I'd like to get feedback on the general code style first.
#include &lt;fstream&gt;
#include &lt;iostream&gt;
#include &lt;regex&gt;
#include &lt;sstream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;

class TextManipulator {
 public:
  static std::string replace(std::string &amp;string, const std::string pattern,
                             const std::string toreplace) {
    return std::regex_replace(string, std::regex(pattern), toreplace);
  }

  static std::string toLowerCase(std::string &amp;string) {
    std::locale loc;
    std::string res;
    for (auto elem : string) {
      res += std::tolower(elem, loc);
    }
    return res;
  }

  static std::vector&lt;std::string&gt; split(const std::string &amp;text,
                                        char seperator) {
    std::vector&lt;std::string&gt; tokens;
    std::size_t start = 0, end = 0;
    while ((end = text.find(seperator, start)) != std::string::npos) {
      std::string extr = text.substr(start, end - start);
      if (!extr.empty()) {
        tokens.push_back(extr);
      }
      start = end + 1;
    }
    tokens.push_back(text.substr(start));
    return tokens;
  }
};

int main() {
  std::ifstream input(
      &quot;/example_docs/Pride_and_Prejudice.txt&quot;);
  std::stringstream buffer;
  buffer &lt;&lt; input.rdbuf();
  std::string text = buffer.str();

  text = TextManipulator::replace(text, &quot;\r\n&quot;, &quot; &quot;);
  text = TextManipulator::replace(text, &quot;,&quot;, &quot;&quot;);
  text = TextManipulator::replace(text, &quot;:&quot;, &quot;&quot;);
  text = TextManipulator::replace(text, &quot;.&quot;, &quot;&quot;);
  text = TextManipulator::toLowerCase(text);
  std::vector&lt;std::string&gt; tokens = TextManipulator::split(text, ' ');

  return 0;
}
Don't use a class
There is no need to create a class just to hold a collection of static functions. Instead, just declare the functions in the global namespace. If you want to avoid polluting the global namespace, consider putting them in a namespace instead, like so:
namespace TextManipulation {

std::string replace(...) {
    ...
};

...
}

Don't write unnecessary trivial wrapper functions
There is no need to create TextManipulator::replace(), when all it does is call std::regex_replace with almost exactly the same arguments. Why not call std::regex_replace() directly instead?
The name replace() also hides the fact that pattern is a regular expression.
Consider renaming toLowerCase() to tolower()
It's a bit annoying to have different naming conventions in one program, and since you already have tolower() for single characters, it would be very convenient to reuse that for whole strings as well. So:
std::string tolower(const std::string &amp;str) {
    ...
}

Note: you forget to add const to the function parameter here, as well as for the first parameter of replace(), but you did it correctly for the other string parameters.