user2088807
user2088807

Reputation: 1408

Replace only whole words c#

I'm trying to create a function replacing only whole words, for example:

The sentence : "#testing is #test", if I use Replace("#test", "#cool"), I'll have "#cooling if #cool" but I'd like to have "#testing is #cool"

I've searched and every answer found was :

string pattern = @"\b"+previousText+"\b";
string myText = Regex.Replace(input, pattern, newText, RegexOptions.IgnoreCase);

However this solution does not work if my previousText (the one I'd like to replace) contains a "#".

Both my previousText and my newText can start with a "#".

What is the solution for this ?

EDIT : Thanks to Legends the regex now works if the word is followed by a space but fails if the searched word is next to a comma :

string input = "#test, #test";
            string patternTest = @"#test";
            string newTextTest = "#cool";
            string result = Regex.Replace(input, @"(?:(?<=^|\s)(?=\S|$)|(?<=^|\S)(?=\s|$))" + patternTest + @"(?:(?<=^|\s)(?=\S|$)|(?<=^|\S)(?=\s|$))", newTextTest, RegexOptions.IgnoreCase);

this returns : "#test, #cool" instead of "#cool, #cool"

Upvotes: 0

Views: 2072

Answers (2)

Legends
Legends

Reputation: 22672

The following Regex will replace only single whole words!

var input = "#testing is #test";
var pattern = @"#test";
string myText = 
Regex.Replace(input, @"(?:(?<=^|\s)(?=\S|$)|(?<=^|\S)(?=\s|$))" + pattern + @"(?:(?<=^|\s)(?=\S|$)|(?<=^|\S)(?=\s|$))","#cool", RegexOptions.IgnoreCase);


Result:

#testing is #cool


This should work with commas and semicolons directly before and after the word:

var input = "#test, is ;#test";
var searchString = @"#test";
var replaceWith = "#cool";
var pattern = @"(?:(?<=^|(\s|,|;))(?=\S|$)|(?<=^|\S)(?=\s|$))" 
              + searchString + 
              @"(?:(?<=^|(\s))(?=\S|$)|(?<=^|\S)(?=(\s|,|;)|$))";

string myText = Regex.Replace(input, pattern, replaceWith, RegexOptions.IgnoreCase);

Result:

#cool, is ;#cool


This one will work with all the following characters before and after the word

For example:

  1. ,word or word,
  2. word; or ;word
  3. .word or ....

, ; . - '

var input = "#test's is #test.";
var searchString = @"#test";
var replaceWith = "#cool";
var pattern = @"(?:(?<=^|(\s|,|;|-|:|\.|'))(?=\S|$)|(?<=^|\S)(?=\s|$))" 
              + searchString + 
              @"(?:(?<=^|(\s))(?=\S|$)|(?<=^|\S)(?=(\s|,|;|-|:|\.|')|$))";
string myText = Regex.Replace(input,pattern ,replaceWith, RegexOptions.IgnoreCase);

Result:

#cool's is #cool.

Upvotes: 2

Noctis
Noctis

Reputation: 11763

If you don't want to use regex for some reason, you can do it without it as well:

var split_options = new [] {' ', '.', ',' ...}; // Use whatever you might have here.
var input =  "#testing is #test".Split( split_options
                                      , StringSplitOptions.RemoveEmptyEntries);
var word_to_replace = "#test";
var new_text = "#cool";
for (int i = 0; i < input.Length; i++)
{
    if (input[i].Equals(word_to_replace))
    input[i] = new_text;
}
var output = string.Join(" ",input);

// your output is "#testing is #cool"

You can put this in a method or extension method, and it'll make you're code cleaner as well.

Upvotes: 2

Related Questions