[Bug]: MSBuild automatically escapes all my strings for me with seemingly no way to have it not do that?
Issue Description
I need to add the following to an ItemGroup: Foo..%2a;Bar..%2a
This is because if I put Foo..;Bar.., I'm intending to split 2 regex expressions into a list. But MSBuild thinks it's a WildCard.
However, if I try to replace * with %2A, MSBuild automatically converts my semi-colon to %3b.
Therefore, when I add my property to an ItemGroup to split on semi-colon, it becomes one single entry with Foo.;Bar.
Steps to Reproduce
I have a propertygroup I'm building with wildcards:
<PropertyGroup>
<MyProperty>Foo*;Bar*</MyProperty>
</PropertyGroup>
I want to use my property to filter PackageReferences, which are not inherently Files, so the WildCard syntax won't work if I try to Include them.
So I've decided to turn my WildCard into Regex
<PropertyGroup>
<MyProperty>Foo*;Bar*</MyProperty>
<MyProperty>$(MyProperty.Replace(".","\.").Replace("*",".*").Replace("?",".").Replace("*", "%2A"))</MyProperty>
</PropertyGroup>
Expected Behavior
What I expect to see is: MyProperty="Foo..%2A;Bar..%2A"
Actual Behavior
What I instead see is: MyProperty="Foo..%2a%3bBar..%2a"
Analysis
No response
Versions & Configurations
MSBuild version 17.8.3+195e7f5a3 for .NET 17.8.3.51904
I seem to have found an awful, awful workaround:
<PropertyGroup>
<Foo>$([MSBuild]::Unescape($(MyProperty.Replace(".","\.").Replace("*",".*").Replace("?",".").Replace("*", "%2A").Replace("%2A","%25252A"))))</Foo>
</PropertyGroup>
The thing is, if I do %252A, thinking that it'll unescape to %2A, it seems to double-expand so I have to %25252A to expand %2525 into %25 which will then expand into %.
There's gotta be another way, as this kind of double unescape behavior seems like the kind of thing that can and will break without warning in a future iteration.
We can see how this can be confusing, we will expand the documentation on how our escaping works so it is less confusing.
As for the break / change in future iterations, we consider any change to the escape behaviour a breaking change. As such, if we decided in the future to make changes to the escaping (we have no plans for such thing now) it will be implemented with Changewaves.