Reputation: 1769
I'm processing some text using C# and I need a regex to replace the spaces in a file link with %20
. So given this text:
/*
** 2 > 1
** 1 < 2
** <file:\\\server\dir one\dirtwo\file name.txt>
** <just because>
** 1 < 2
** 2 > 1
** <file:\\\server\dir one\dirtwo\file name.txt>
** 2 > 1
*/
The result would be:
/*
** 2 > 1
** 1 < 2
** <file:\\\server\dir%20one\dirtwo\file%20name.txt>
** <just because>
** 1 < 2
** 2 > 1
** <file:\\\server\dir%20one\dirtwo\file%20name.txt>
** 2 > 1
*/
So far I've come up with this pattern \x20(?=(?:(?!<file:).)*>)
but it matches some of the spaces that are outside of the file link.
Ideally I'd like to do this just using regex. The text I'm modifying is the current document open in Visual Studio (I've created a VS extension). For some other text changes I'm using the ReplacePattern
method in EnvDTE.TextDocument
. I don't have much experience writing extensions so this seemed a lot simpler than anything else I could come up with (I did look at using edit points).
There seems to be an issue with using lookbehind or lookahead in a regex using the TextDocument.ReplacePattern method which causes an exception to be raised. Using the same expression in Regex.Replace works as expected. If it wasn't for this issue then the solution(s) provided by Wiktor Stribiżew would be perfect.
To keep things simple I've implemented the following which does the job:
bool patternReplaced;
do
{
patternReplaced = activeDoc.ReplacePattern(@"(<file:\\{3}.*)\s(\S+>)", @"$1%20$2", (int)vsFindOptions.vsFindOptionsRegularExpression);
} while (patternReplaced);
Upvotes: 2
Views: 156
Reputation: 627087
You can use a Regex.Replace
to match the <file:...>
substrings and replace the spaces using the match evaluator:
var res = Regex.Replace(str, @"<file:\\{3}[^>]+>", m => m.Value.Replace(" ", "%20"));
See the IDEONE demo
Note that in case there are more than just spaces to escape, you can consider using Uri.EscapeUriString(m.Value)
(with another regex, like @"(?<=<file:\\{3}[^<>]*)[^<>\\]+"
).
Another solution using infinite width lookbehind:
@"(?<=<file:\\{3}[^<>]*)\s"
and replace with %20
.
See this regex demo
Upvotes: 1