2

Given a string (a path) that matches /dir1/, I need to replace all spaces with dashes.

Ex: /dir1/path with spaces should become /dir1/path-with-spaces.

This could easily be done in 2 steps...

var rgx = new Regex(@"^\/dir1\/");
var path = "/dir1/path with spaces";
if (rgx.isMatch(path))
{
    path = (new Regex(@" |\%20")).Replace(path, "-");
}

Unfortunately for me, the application is already built with a simple RegEx replace and cannot be modified, so I need to have the RegEx do the work. I thought I had found the answer here: regex: how to replace all occurrences of a string within another string, if the original string matches some filter

And was able create and test (?:\G(?!^)|^(?=\/dir1\/.*$)).*?\K( |\%20), but then I learned it does not work in this app because the \K is an unrecognized escape sequence (not supported in .NET).

I also tried a positive lookbehind, but I wasn't able to get it to replace all the spaces (only the last if the match was greedy or the first if not greedy). I could put in enough checks to handle the max number of spaces, but as soon as I check for 10 spaces, someone will pass in a path with 11 spaces.

Is there a RegEx only solution for this problem that will work in the .NET engine?

thadmiller
  • 539
  • 1
  • 4
  • 19

1 Answers1

2

You can leverage the unlimited width lookbehind pattern in .NET:

Regex.Replace(path, @"(?<=^/dir1/.*?)(?: |%20)", "-")

See the regex demo

enter image description here

Regex details

  • (?<=^/dir1/.*?) - a positive lookbehind that matches a location that is immediately preceded with /dir1/ and then any zero or more chars other than a newline char, as few as possible
  • (?: |%20) - either a space or %20 substring.
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • That is working perfectly, thank you. I should have been using a .NET tester and I might have stumbled on the solution. However, for my education, why the `?` in the `.*?`? Also, why `(?: |%20)` and not just `( |%20)`? – thadmiller Oct 28 '20 at 17:34
  • @thadmiller `(?:...)` is a non-capturing group, since you do not need to value of the group, no need to capture the value. I use `.*?` out of habit, `.*` will work in a similar way here. – Wiktor Stribiżew Oct 28 '20 at 17:41