views:

264

answers:

2

I'm not very good at regex but maybe there's a simple way to achieve this task.

I'm given a string like "bla @a bla @a1 bla"

I'm also given pairs like {"a", "a2"} , {"a1", "a13"}, and I need to replace @a with @a2 for the first pair, and @a1 with @a13 for the second one.

The problem is when i use String.Replace and look for @a, it also replaces @a1 but it should not. I need it to completely match @a and avoid partially matching it in other places.

Note: the given string could also be brackets, commas, dots and so on. However, pairs will always be [a-z]*[0-9]+

Help me with regex replace, please.

Cheers

+3  A: 

Use \b:

@a\b

\b is a zero width word boundary. Basically what this means is it matches a transition from word characters (letters, digits, underscore) to non-word characters (everything else) or vice versa but doesn't "consume" any part of the input (that's the zero-width part).

For example:

string s1 = "bla @a bla @a1 bla ";
string s2 = Regex.Replace(s1, @"@a\b", "foo");
Console.WriteLine(s2);

Output:

bla foo bla @a1 bla
cletus
but will it work for replacing `a1` and not replacing `a11` ?
vittore
@vittore, yes. But why don't you test it for yourself?
Anthony Pegram
it works thanks!
vittore
+2  A: 

Use a regular expression with a lookbehind and a word boundary:

Regex regex = new Regex(string.Format(@"(?<!\w)@{0}\b", from));
string result = regex.Replace(input, "@" + to)

Note: I am using here the fact that your pairs are known to be alphanumeric. If this turns out not to be the case, the above will not work.

Alternatively you don't need regular expressions for this task. You could just split your input on spaces (assuming that spaces are always the separators), iterate over the parts and find and replace those you are looking for, then rejoin to form the final result.

string result = string.Join(" ",
    input.Split(' ')
         .Select(x => x == "@" + from ? "@" + to : x)
         .ToArray());
Mark Byers
Spaces not the only separators
vittore
@vittore: Then the second method won't work in this case. I'd stick with regular expressions.
Mark Byers
thanks, just \b works just fine! missed it before
vittore