Regex replaces nth element with string and add custom HTML tags

I have a list of words "this", "be able", "it"

that I want to find inside a paragraph, so I can replace saving my capitalization.

Having this paragraph:

This is my text and that's why I want to match it! Since this is just a text, I would like to be able to solve it. This is the final phrase of this paragraph.

"this"

found 5 times and if I decide to replace the 4th ( "this"

) I want to keep the T-capital. Now you will see that it is not actually a replacement, but a big problem with the addition, since the actual replacement will be from this

to this

so my last point:

This is my text and that's why I want to match it! Since this is just a text, I would like to solve it. This is the last phrase of this paragraph.

My code:

    List<string> words = new List<string>(new string[] { "this", "be able", "it"});
    var paragraph = "This is my text and this is why I want to match it! As this is just a text, I would like to be able to solve it. This is the final phrase of this paragraph.";
    //List<string> 
    for (int w = 0; w < words.Count; w++)
    {
        var foudItems = Regex.Matches(paragraph, @"\b" + words[w] + "\\b", RegexOptions.IgnoreCase);

        if (foudItems.Count != 0)
        {
            Random rnd = new Random();
            int rndWord = rnd.Next(0, foudItems.Count);
            Regex.Replace(paragraph, @"\b" + words[w] + "\\b", "<strong>" + foudItems[rndWord] + "</strong>");
            Console.WriteLine(paragraph);
        }

        //Regex.Replace()
        Console.WriteLine(foudItems[0] + " " + foudItems[1]);
}

      

The main problem is that I don't know how to replace only the nth word using regex. Another problem will be a complex approach in solving this issue, so I am open to new suggestions.

+3


source to share


2 answers


If you want to replace the nth occurrence of something, you can use a delegate MatchEvaluator

that checks the current index of the occurrence and returns an unmodified consistent value if the index match is not the one you want to replace. To keep track of the current index, you can grab a local variable:

int occurrenceToReplace = 4;
int index = 0;
MatchEvaluator evaluator = m => (++index == occurrenceToReplace)
    ? $"<strong>{m.Value}</strong>"
    : m.Value;

text = Regex.Replace(text, @"\bthis\b", evaluator, RegexOptions.IgnoreCase);

      


Now, back to your problem - you can write a method that wraps the nth occurrence of a given word in an html tag:

private static string MakeStrong(string text, string word, int occurrence)
{
    int index = 0;
    MatchEvaluator evaluator = m => (++index == occurrence)
         ? $"<strong>{m.Value}</strong>"
         : m.Value;
    return Regex.Replace(text, $@"\b{word}\b", evaluator, RegexOptions.IgnoreCase);
}

      



And if you want to accidentally replace one of the occurrences of each word, just use this method in a loop:

string[] words = { "this", "be able", "it"};   
var paragraph = @"This is my text and this is why I want to match it! As this is just
a text, I would like to be able to solve it. This is the final phrase of this paragraph.";

var random = new Random();
foreach(var word in words)
{
    int count = Regex.Matches(paragraph, $@"\b{word}\b", RegexOptions.IgnoreCase).Count;
    int occurrence = random.Next(count + 1);
    paragraph = MakeStrong(paragraph, word, occurrence);
}

      

Output example:

This is my text and this one , so I want to combine it ! Since this is just a text, I would like to be able to resolve it. This is the final phrase of this paragraph.

+2


source


If you want the regex to be pretty simple, you can use this algorithm:



List<string> words = new List<string>(new string[] { "this", "be able", "it" });
var paragraph = "This is my text and this is why I want to match it! As this is just a text, I would like to be able to solve it. This is the final phrase of this paragraph.";
//List<string> 
foreach (string word in words)
{
    var foundItems = Regex.Matches(paragraph, @"\b" + word + @"\b", RegexOptions.IgnoreCase);
    if (foundItems.Count != 0)
    {
        var count = 0;
        var toReplace = 3;
        foreach (Match foudItem in foundItems)
        {
            count++;
            if(count != toReplace)
                continue;

            var regex = $"(^.{{{foudItem.Index}}}){foudItem.Value}(.*)";
            paragraph = Regex.Replace(paragraph, regex, $"$1<strong>{foudItem.Value}</strong>$2");
        }
        Console.WriteLine(paragraph);
    }
    Console.WriteLine(foundItems[0] + " " + foundItems[1]);
}

      

0


source







All Articles