Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing each instance of a word in a string with a unique value

Tags:

c#

regex

Within a string, I'm trying to update multiple instances of the same word with different values.

This is an overly simplified example, but given the following string:

"The first car I saw was color, the second car was color and the third car was color"

The first instance of the word color I want to replace with "red", the second instance should be "green" and the third instance should be "blue".

What I thought to try was a regex pattern to find boundried words, interate through a loop and replace them one at a time. See the example code below.

var colors = new List<string>{ "reg", "green", "blue" };
var sentence = "The first car I saw was color, the second car was color and the third car was color";

foreach(var color in colors)
{
    var regex = new Regex("(\b[color]+\b)");
    sentence = regex.Replace(sentence, color, 1);
}

However, the word "color" never gets replaced with the appropriate color name. I can't find what I've been doing wrong.

like image 713
Andy Evans Avatar asked Jun 06 '14 19:06

Andy Evans


People also ask

How do I replace multiples in a string?

Show activity on this post. var str = "I have a cat, a dog, and a goat."; str = str. replace(/goat/i, "cat"); // now str = "I have a cat, a dog, and a cat." str = str. replace(/dog/i, "goat"); // now str = "I have a cat, a goat, and a cat." str = str.

How replace all occurrences of a string in TypeScript?

To replace all occurrences of a string in TypeScript, use the replace() method, passing it a regular expression with the g (global search) flag. For example, str. replace(/old/g, 'new') returns a new string where all occurrences of old are replaced with new .


3 Answers

Try a match delegate.

It is an overload of Regex.Replace() that most folks miss. It simply lets you define a, potentially context sensitive, dynamic handler instead of a hardcoded string to replace with, and could have side-effects. The "i++ %" is a modulo operator is used below to simply cycle through the values. You could use a database or a hash table or anything.

var colors = new List<string> { "red", "green", "blue" };
var sentence = "The first car I saw was color, the second car was color and the third car was color";
int i = 0;
Regex.Replace(sentence, @"\bcolor\b", (m) => { return colors[i++ % colors.Count]; })

This solution works for an arbitrary number of replacements, which is more typical (global replace).

like image 115
codenheim Avatar answered Oct 17 '22 02:10

codenheim


The problem is that in your example, color isn't always preceded and followed by a non-word character. For your example, this worked for me:

var regex = new Regex("\b?(color)\b?");

So this:

var colors = new List<string>{ "red", "green", "blue" };
var sentence = "The first car I saw was color, the second car was color and the third car was color";

foreach(var color in colors)
{
    var regex = new Regex("\b?(color)\b?");
    sentence = regex.Replace(sentence, color, 1);
}

Produces this:

The first car I saw was red, the second car was green and the third car was blue

like image 43
Sven Grosen Avatar answered Oct 17 '22 02:10

Sven Grosen


I try to stay away from Regex whenever possible. It has it's place, but not for simple cases like this IMHO :)

public static class StringHelpers
{
    //Copied from http://stackoverflow.com/questions/141045/how-do-i-replace-the-first-instance-of-a-string-in-net/141076#141076
    public static string ReplaceFirst(this string text, string search, string replace)
    {
        int pos = text.IndexOf(search);
        if (pos < 0)
        {
            return text;
        }
        return text.Substring(0, pos) + replace + text.Substring(pos + search.Length);
    }
}


var colors = new List<string>{ "red", "green", "blue" };
string sentence = colors.Aggregate(
    seed: "The first car I saw was color, the second car was color and the third car was color", 
    func: (agg, color) => agg.ReplaceFirst("color", color));
like image 1
Steven Wexler Avatar answered Oct 17 '22 03:10

Steven Wexler