0

I have a function that should replace any string found in another string with the criteria that the string to replace starts with a @ and it must be replaced only when it is an entire word.

But the code below does not work. The problem is with the character, @, because if I use another character at the start, for example, a X, it works. However even putting the @ symbol between square brackets did not help.

public static string DB_Replace_Str(string st, string stFrom, string stTo)
{         
    stFrom = stFrom.Replace("@", "[@]");//this does not help
    string pattern = @"\b" + stFrom + @"\b";
    return Regex.Replace(st, pattern, stTo);
}

I post some example strings here:

  • st = "SELECT @table_Software.*, @table_Teile.@Id as @TeilId FROM @table_Software LEFT JOIN @table_Teile ON @table_Software.@Id = @table_Teile.@Software_Id WHERE @table_Software.@Id = 11"
  • stFrom = "@table_Software"
  • stTo = "tblSoftware"
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
fsava
  • 35
  • 8
  • 5
    Can you show samples of the strings that you would be passing in the variables `st`, `stFrom` and `stTo` as its currently written it is very hard to understand exactly what you are trying to achieve. – Nico Jun 29 '15 at 06:22
  • From your description it doesn't sound like regex is the right thing to use, C# has plenty of (built in) ways to check what a string contains. – Sayse Jun 29 '15 at 06:27
  • Are these the inputs ? string st = "aaaa @bbb ccc ddd eee fff"; string stFrom = "bbb"; string stTo = "XXX"; string ret = "aaaa XXX ccc ddd eee fff"; ? – Wolf5 Jun 29 '15 at 06:30
  • I am trying to post the strings but I get an error in stackoverflow: "only one additional @user etc...." stackoverflow is also confused by the @ character – fsava Jun 29 '15 at 06:35
  • I don't want to spoil your research but there is a method that "Returns a new string in which all occurrences of a specified string in the current instance are replaced with another specified string." Please read [ask] and try to take the time to format your questions. – Sayse Jun 29 '15 at 06:42
  • @fsava: Is your expected output `SELECT tblSoftware.*, @table_Teile.@Id as @TeilId FROM tblSoftware LEFT JOIN @table_Teile ON tblSoftware.@Id = @table_Teile.@Software_Id WHERE tblSoftware.@Id = 11`? – Wiktor Stribiżew Jun 29 '15 at 07:19
  • @ stribizhev yes it is – fsava Jun 29 '15 at 07:23
  • the normal replace will replace also part of a longer word not only whole words, I need to replace only whole words – fsava Jun 29 '15 at 07:27

2 Answers2

0

You need to remove word boundaries. Because I think there isn't a word boundary exists between the start and [

string pattern = @"(?<!\S)" + stFrom + @"(?!\S)";

or

string pattern = @"\B" + stFrom + @"\B";

Why it works when you put X at the start? Because there is a word boundary exists between X and [.

Avinash Raj
  • 172,303
  • 28
  • 230
  • 274
0

You need to specify the non-word boundary first, and then a word boundary:

Details from Regular-Expressions.info:

\b allows you to perform a "whole words only" search using a regular expression in the form of \bword\b. A "word character" is a character that can be used to form words. All characters that are not "word characters" are "non-word characters".
\B is the negated version of \b. \B matches at every position where \b does not. Effectively, \B matches at any position between two word characters as well as at any position between two non-word characters.

public static string DB_Replace_Str(string st, string stFrom, string stTo)
{
    string pattern = string.Format("\\B{0}\\b", stFrom);
    return Regex.Replace(st, pattern, stTo);
}

Or even:

public static string DB_Replace_Str(string st, string stFrom, string stTo)
{
    return Regex.Replace(st, string.Format("\\B{0}\\b", Regex.Escape(stFrom)), stTo);
}

The output:

SELECT tblSoftware.*,  @table_Teile.@Id as @TeilId FROM tblSoftware LEFT JOIN @table_Teile ON tblSoftware.@Id = @table_Teile.@Software_Id WHERE  tblSoftware.@Id = 11
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • I think we can improve this a bit. Rather than creating a temp variable, we can use the `string.Format...` inside the `Regex.Replace`, and perhaps, we should also escape any metacharacters inside `stFrom` with `Regex.Escape` (although if there are any non-word characters at the end of `stFrom`, we won't get a match :() – Wiktor Stribiżew Jun 29 '15 at 08:08