C# Regex Query

I am after a leg up with the following in C#.

I want to replace various names / alias for one common name.
The input string is one string which contains multiple lines in it. Search to be case insentive.

e.g. master word "Fred Project" to replace :
"Fred." or "Fred. " or "Fred "  (Fred space) but not the Fred in "Fred Project" also NOT "Fred.txt"
(i.e. if Fred is stand alone or at the end of a sentence, then replace, if fred is part of something else, don't)
the project
project fred
project freddy

I don't care if i have to loop a loop for each name or if the expression can handle the lot.
Regex.Replace() is what i am using.

I have it kind of working but don't have the syntax right for the replacement, e.g.
Freddy considerations => Fred Projectconsiderations  (WRONG)
Freddy considerations => Fred Project considerations  (RIGHT)

That is because although my match works (Freddy(\s?)) the system thinks my replacement string needs to include the extra whitespace characters...

Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Patrick MatthewsCommented:
Set your Regex object to ignore case, and then try using a pattern string of:

    (fred[a-z]*( +project)?)(?=$|[ \.,!\?:;])

with replacement text of:

    Fred Project
käµfm³d 👽Commented:
How about:


    Fred Project

Open in new window

käµfm³d 👽Commented:
If neither solution works for you, could you please provide sample inputs with expected outputs of the form:

    input  = output
    input  = output
    input  = output

The format is really arbitrary, but we are just looking to see *exactly* what you expect to receive. I'm not sure about others, but I was a little confused by the description of expected output above  :)
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.


  I have attached sample code.it will be correct if I am understanding correctly :)
we are having string to be replaced in an array (patternsFind )
@"(\s|\.\s|\.$|,) :  the common symbols allowed after searching word .searching word can be followed by only space or dot followed  by space or dot followed by nothing ( lat word) or by comma.here you can add any delimiter if you want; the word "project" may proceed or follow the searching word. so, the pattern becomes
 newpattern =string.Format("{0}?{1}{2}+{0}?",@"(project\s)",pattern,commonpattern);

and now after finding every match , we have to add the common symbols in find pattern in replace pattern to get like Freddy considerations => Fred Project considerations. it is done by match evaluator delegate. it invokes GetReplaceString method for each match in replace function where we are adding common symbols. hope this helps.

PS :the code having all static methods and static variable for console application. you can have it as instance methods and variables.

class Program
        static string[] patternsFind = new string[] { "Fred", "Freddy", "the project" }; 
        static string commonpattern = @"(\s|\.\s|\.$|,)";
        static void Main(string[] args)
            string input = @"Fred or FRED is stand alone or at the end of a sentence, then replace fred. 
            Don't replace in frededword or in fred.txt or in Fred Project or in project.
            The words Freddy,the project,project fred,project freddy are to be replaced with fred.";
            foreach (string pattern in patternsFind)
                string newpattern =string.Format("{0}?{1}{2}+{0}?",@"(project\s)",pattern,commonpattern); 
                input = Regex.Replace(input, newpattern,new MatchEvaluator(GetReplaceString),RegexOptions.IgnoreCase | RegexOptions.Multiline);
        static string GetReplaceString(Match m)
            string replacepattern = "Fred Project";
            MatchCollection newMatch  = Regex.Matches (m.Value, commonpattern,RegexOptions.IgnoreCase);
            foreach (Match suffix in newMatch)
                replacepattern = replacepattern + suffix.Value;
            return replacepattern; 

Open in new window


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
greg_robertsAuthor Commented:
Thanks All

matthewspatrick - This didn't cover the fred.txt case and i was going to do a follow up for an explanation but others have covered.

Mathiyazhagan - Brillant response, explanation and an example. You should write msdn doco !!
Your code works!! Love the way you did an exampel to prove it.
I have to be careful in the order of my word "patternsFind" as i can end up with double up. Once i changed the order all fine.

NB:  string newpattern =string.Format("{0}?{1}{2}+{0}?",@"(project\s)"
My reference to not replacing the "Fred" in "Fred Project" was a generic reference to avoid getting a "Fred Project Project" effect. The "project" could be any term.
What i was trying to say is when you find the replacepattern already in the string then either ignore or replace completely (pref. the later cause this corrects the wrong case situations, e.g. "fred Project").
In another replace example the "Fred Project" master term example might be "John" or "Project Fred".

So in this context, what does newpattern look like ?

The thing i was struggling with was how to say "xxx. " "xxx yyy" ok but "xxx.yyy" no
I think this is what your commonpattern does.

Thanks again

greg_robertsAuthor Commented:
p.s. I think
                            string newpattern = string.Format("{0}{1}+", name, commonpattern);
is the generic form ?
  Glad to see that I helped you .  
>>  string newpattern = string.Format("{0}{1}+", name, commonpattern); - is the generic form ?
  yes, you can use it as generic form with some more extra delimeters in common pattern.

Thanks for your compliments.Thank you.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.