ELBartoTn
ELBartoTn

Reputation: 137

Insert space when needed with Regex in c#

I have to write a function that looks up for a string and check if is followed/preceded by a blank space, and if not add it here is my try :

public string AddSpaceIfNeeded(string originalValue, string targetValue)
    {
        if (originalValue.Contains(targetValue))
        {
            if (!originalValue.StartsWith(targetValue))
            {
                int targetValueIndex = originalValue.IndexOf(targetValue);
                if (!char.IsWhiteSpace(originalValue[targetValueIndex - 1]))
                    originalValue.Insert(targetValueIndex - 1, " ");
            }
            if (!originalValue.EndsWith(targetValue))
            {
                int targetValueIndex = originalValue.IndexOf(targetValue);
                if (!char.IsWhiteSpace(originalValue[targetValueIndex + targetValue.Length + 1]) && !originalValue[targetValueIndex + targetValue.Length + 1].Equals("(s)"))
                    originalValue.Insert(targetValueIndex + targetValue.Length + 1, " ");
            }
        }
        return originalValue;
    }

I want to try with Regex : I tried like this for adding spaces after the targetValue :

Regex spaceRegex = new Regex("(" + targetValue + ")(?!,)(?!!)(?!(s))(?= )");
originalValue = spaceRegex.Replace(originalValue, (Match m) => m.ToString() + " ");

But not working, and I don't really know for adding space before the word.

Example adding space after: AddSpaceIfNeeded(Hello my nameis ElBarto, name) => Output Hello my name is ElBarto

Example adding space before: AddSpaceIfNeeded(Hello myname is ElBarto, name) => Output Hello my name is ElBarto

Upvotes: 1

Views: 167

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626825

You may match your word in all three context while capturing them in separate groups and test for a match later in the match evaluator:

public static string AddSpaceIfNeeded(string originalValue, string targetValue) 
{
  return Regex.Replace(originalValue, 
        $@"(?<=\S)({targetValue})(?=\S)|(?<=\S)({targetValue})(?!\S)|(?<!\S){targetValue}(?=\S)", m => 
          m.Groups[1].Success ? $" {targetValue} " : 
           m.Groups[2].Success ? $" {targetValue}" : 
            $"{targetValue} ");
}

See the C# demo

Note you may need to use Regex.Escape(targetValue) to escape any sepcial chars in the string used as a dynamic pattern.

Pattern details

  • (?<=\S)({targetValue})(?=\S) - a targetValue that is preceded with a non-whitespace ((?<=\S)) and followed with a non-whitespace ((?=\S))
  • | - or
  • (?<=\S)({targetValue})(?!\S) - a targetValue that is preceded with a non-whitespace ((?<=\S)) and not followed with a non-whitespace ((?!\S))
  • | - or
  • (?<!\S){targetValue}(?=\S) - a targetValue that is not preceded with a non-whitespace ((?<!\S)) and followed with a non-whitespace ((?!\S))

When m.Groups[1].Success is true, the whole value should be enclosed with spaces. When m.Groups[2].Success is true, we need to add a space before the value. Else, we add a space after the value.

Upvotes: 2

Related Questions